using System;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectPlay;
using Microsoft.DirectX.DirectInput;

using DarkStrideToolbox;


namespace MetalMarines
{
	public enum enumSquareStatus
	{
		Empty,
		Building,
		Built,
		Destroyed
	};

	public class Square
	{
		#region Properties
		private long m_nHeight = 0;
		private int m_nType = Game.m_cDEFAULTTERRAINKEY;
		private enumSquareStatus m_nStatus = enumSquareStatus.Empty;
		private double m_nScarPercent = 0;
		private long m_nGobBuildingKey = -10;
		private double m_nBuildingProgress = 0;
		private bool m_bArmed = false;
		private double m_nRearmingProgress = 0;
		private long m_nX = 0;
		private long m_nY = 0;
		private long m_nAnimationFrame = 0;
		private double m_nTimeSinceFrameLastChange = 0;
		private double m_nStrength = 0;
		private double m_nMMStrength = 0;
		private long m_nMMX = 0;
		private long m_nMMY = 0;
		private double m_nMMPosOffsetX = 0;
		private double m_nMMPosOffsetY = 0;
		private long m_nMMDirection = 0;
		private bool m_bMMFiring = false;
		private long m_nMMAnimationCell = 0;
		private double m_nMMTimeSinceAnimationChange = 0;
		private bool m_bMMIsOverseas = false;
		private long m_nUnderCamoBuildingKey = Game.m_cCAMO_NOCAMOBUILT;
		private int m_nSoundIndex = -1;
		private string m_sSoundKey = "";

		private string m_sScrollingMessage = "";
		private double m_nScrollingMessagePercentDone = 1;
		private System.Drawing.Color m_oScrollingMessageColor = System.Drawing.Color.White;

		private bool m_bDefenseHasFiredAtMMThisRound = false;

		//m_cGOB_BLDSTATS_ISARROW_CLMN
		private double m_nArrow_TimeSinceStateChange = 0;
		private bool m_bArrow_Rendering = true;

		private bool m_bNeedToBeSent = false;

		private static string m_cSQUARE_SEP = "[SS]";
		private Game m_oGame = null;
		#endregion


		public Square( Game oGame )
		{
			m_oGame = oGame;
		}


		public void Advance( double nElapsedTime,double nBuildPerSecond,Island oIsland,bool bMyIsland )
		{
			double nBuildTime = 0;
			double nTimeBetweenFrames = 0;
			long nBuildingGobIndex;
			long nFrameMax = 0;
			int nIndex = -1;


			m_bDefenseHasFiredAtMMThisRound = false;

			if( m_nScrollingMessagePercentDone < 1 )
			{
				m_nScrollingMessagePercentDone += nElapsedTime;
			}

			m_nArrow_TimeSinceStateChange += nElapsedTime;
			if( m_nArrow_TimeSinceStateChange > 1 )
			{ 
				m_nArrow_TimeSinceStateChange = 0; 
				m_bArrow_Rendering = !m_bArrow_Rendering;
			}

			if( m_nStatus == enumSquareStatus.Built )
			{
				nFrameMax			= (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_ANIMNUMCELLS_CLMN );
				nTimeBetweenFrames	= (double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_ANIMCELLDELAY_CLMN );

				if( m_nStrength <= 0 )
				{
					this.SquareStatus = enumSquareStatus.Destroyed;
				}
			}
			else if( this.SquareStatus == enumSquareStatus.Destroyed && 
					 m_oGame.UseBuildingRot == true )
			{
				if( m_nStrength >= -100 && m_nGobBuildingKey >= 0 )
				{
					m_nStrength -= nElapsedTime * 1.2;
				}                				
				else if( m_nScarPercent > 0 )
				{
					m_nScarPercent -= nElapsedTime * .04;
					if( m_nScarPercent < 0 )
					{
						m_nScarPercent = 0;
					}
				}
				else if( m_nGobBuildingKey < 0 ||
						 (bool)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_CANROTTONOTHING_CLMN ) == true )
				{
					this.SquareStatus = enumSquareStatus.Empty;
				}
			}
			else if( this.SquareStatus == enumSquareStatus.Building && bMyIsland == true )
			{
				//Cycle our sound if we need to
				if( m_nSoundIndex != -1 &&
					m_oGame.GameEngine.DirectSound.SoundIsStillPlaying( m_sSoundKey,m_nSoundIndex ) == false )
				{
					m_nSoundIndex = -1;
					m_sSoundKey = "";
					//m_oGame.NumberOfConstructionSoundsPlaying--;					
				}
				else if( m_nSoundIndex == -1 && 
						 CanPlayConstructionSound() == true &&
						 //m_oGame.NumberOfConstructionSoundsPlaying < 2 &&
						 oIsland.IsMyIsland() == true )
				{
					//m_oGame.NumberOfConstructionSoundsPlaying++;
					nIndex = DSMisc.GetRnd( 0,Game.m_cGOB_SOUND_CONSTRUCTION.Length-1 );
					m_sSoundKey = Game.m_cGOB_SOUND_CONSTRUCTION[ nIndex ];
					m_nSoundIndex = m_oGame.GameEngine.DirectSound.PlaySound( m_sSoundKey );
				}

				nBuildTime = (double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_BLDTIME_CLMN );
				m_nBuildingProgress += nElapsedTime * nBuildPerSecond;

				if( m_nBuildingProgress < nBuildTime * 0.33 )
				{
					nBuildingGobIndex = Game.m_cGOB_UNDRCONSTR_LVL1_KEY;
				}
				else if( m_nBuildingProgress < nBuildTime * 0.66 )
				{
					nBuildingGobIndex = Game.m_cGOB_UNDRCONSTR_LVL2_KEY;
				}
				else
				{
					nBuildingGobIndex = Game.m_cGOB_UNDRCONSTR_LVL3_KEY;
				}

				if( m_nBuildingProgress >= nBuildTime || nBuildTime == 0 || m_oGame.Debug_InstantBuild == true )
				{
					//If the build is done then stop the sound
					if( m_nSoundIndex != -1 )
					{
						m_oGame.GameEngine.DirectSound.StopPlayingSound( m_sSoundKey,m_nSoundIndex );
						m_sSoundKey = "";
						m_nSoundIndex = -1;
						//m_oGame.NumberOfConstructionSoundsPlaying--;
					}

					this.SquareStatus = enumSquareStatus.Built;
					m_nAnimationFrame = 0;
					m_nTimeSinceFrameLastChange = 0;
					m_nStrength = (double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_STRENGTH_CLMN );
				}
				else
				{
					nFrameMax			= (long)Game.GetBldStat( nBuildingGobIndex,Game.m_cGOB_BLDSTATS_ANIMNUMCELLS_CLMN );
					nTimeBetweenFrames	= (double)Game.GetBldStat( nBuildingGobIndex,Game.m_cGOB_BLDSTATS_ANIMCELLDELAY_CLMN );
				}
			}

			//Move our animation forward!
			m_nTimeSinceFrameLastChange += nElapsedTime;
			if( nTimeBetweenFrames < m_nTimeSinceFrameLastChange )
			{
				m_nTimeSinceFrameLastChange = 0;

				//Oops... ran off the bottom of the frames.  Start us back over at the top.
				m_nAnimationFrame++;
				if( m_nAnimationFrame >= nFrameMax )
				{
					m_nAnimationFrame = 0;
				}
			}

			if( this.SquareStatus == enumSquareStatus.Built && m_bArmed == false &&
				Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_RECHARGEPRCNT_CLMN ) != null &&
				bMyIsland == true )
			{
				//This means a building is recharging
				m_nRearmingProgress += nElapsedTime * 
										(double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_RECHARGEPRCNT_CLMN );

				if( m_nRearmingProgress >= 100 )
				{
					m_bArmed = true;
				}
			}
		}

		public void FireWeapon()
		{
			m_nRearmingProgress = 0;
			m_bArmed = false;
			m_bMMIsOverseas = true;
		}


		public void RenderTerrain( DSGraphicsWrapper oDSGraphicsWrapper, System.Drawing.Rectangle oTrgRect, 
								   System.Drawing.Rectangle oClipRect, long nSquareW, long nSquareH,
								   System.Drawing.Color cColor,Island oIsland )
		{
			int nGraphicIndex = 0;
			int nColorMask = 0;
			int nColor = 0;
			string sGraphicKey = "";
			System.Drawing.Rectangle oSrcRect;


			if( cColor.ToArgb() != System.Drawing.Color.White.ToArgb() )
			{
				//nColorMask = System.Drawing.Color.Navy.ToArgb();
				nColorMask = cColor.ToArgb();
			}
			else if( this.SquareStatus == enumSquareStatus.Destroyed )
			{
				nColor = (int)Math.Floor( (double)128 * m_nScarPercent );
				nColor = 255 - nColor;
				nColorMask = System.Drawing.Color.FromArgb( nColor,nColor,nColor ).ToArgb();

				//System.Drawing.Color oC = System.Drawing.Color.Gray; 
				//nColorMask = System.Drawing.Color.Gray.ToArgb();
			}
			else
			{
				nColorMask = System.Drawing.Color.White.ToArgb();
			}

			/*if( oIsland.Direction == 0 )
			{*/
				nGraphicIndex = (int)Game.GetTrnStat( m_nType,Game.m_cGOB_TRNSTATS_GRAPHICINDEX_DIR0_CLMN );
			/*}
			else if( oIsland.Direction == 1 )
			{
				nGraphicIndex = (int)Game.GetTrnStat( m_nType,Game.m_cGOB_TRNSTATS_GRAPHICINDEX_DIR1_CLMN );
			}
			else if( oIsland.Direction == 2 )
			{
				nGraphicIndex = (int)Game.GetTrnStat( m_nType,Game.m_cGOB_TRNSTATS_GRAPHICINDEX_DIR2_CLMN );
			}
			else if( oIsland.Direction == 3 )
			{
				nGraphicIndex = (int)Game.GetTrnStat( m_nType,Game.m_cGOB_TRNSTATS_GRAPHICINDEX_DIR3_CLMN );
			}*/

			oSrcRect = Game.GetSrcRectForTerrainType( nGraphicIndex,ref sGraphicKey );

			oDSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, oTrgRect, oClipRect,
												new Vector2( Game.m_cSQRW_TRN/2,Game.m_cSQRH_TRN/2 ), 
												0, 0, false, nColorMask );
		}
		public long RenderBuilding( DSGraphicsWrapper oDSGraphicsWrapper, System.Drawing.Rectangle oTrgRect, 
								    System.Drawing.Rectangle oClipRect, long nSquareW, long nSquareH,
									System.Drawing.Color cColor,Island oIsland,DSSortedList oGroups )
		{
			bool bRender = true;
			object oBuilding = null;
			System.Drawing.Rectangle oSrcRect = System.Drawing.Rectangle.Empty;
			DSSortedList oGroup = null;
			long nEmptyIndex = -1;
			long nGraphicIndex = -1;
			long nBuildingIndex = -1;
			int nColorMask = 0;
			double nBuildTime = 0;
			string sGraphicKey = "";
			string sGroupNum = "";


			/*if( bRenderBlue == true )
			{
				nColorMask = System.Drawing.Color.Navy.ToArgb();
			}
			else
			{
				nColorMask = System.Drawing.Color.White.ToArgb();
			}*/
			nColorMask = cColor.ToArgb();

			if( this.SquareStatus == enumSquareStatus.Building )
			{
				nBuildTime = (double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_BLDTIME_CLMN );

				if( m_nBuildingProgress < nBuildTime * 0.33 )
				{
					nBuildingIndex = Game.m_cGOB_UNDRCONSTR_LVL1_KEY;
				}
				else if( m_nBuildingProgress < nBuildTime * 0.66 )
				{
					nBuildingIndex = Game.m_cGOB_UNDRCONSTR_LVL2_KEY;
				}
				else
				{
					nBuildingIndex = Game.m_cGOB_UNDRCONSTR_LVL3_KEY;
				}
				oSrcRect = Game.GetSrcRectForBuildingByBuildingKey( nBuildingIndex,m_nAnimationFrame,ref sGraphicKey );
			}
			else if( this.SquareStatus == enumSquareStatus.Built &&
					 (bool)Game.GetBldStat( this.GobBuildingKey,Game.m_cGOB_BLDSTATS_ISARROW_CLMN ) == true )
			{
				bRender = m_bArrow_Rendering;
				nGraphicIndex = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );
				oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,oIsland.Direction,ref sGraphicKey );
			}
			else if( this.SquareStatus == enumSquareStatus.Built && m_bArmed == true )
			{
				//Ok turns out that if the building is a marine it may be out walking around
				if( ( m_nMMX != m_nX || m_nMMY != m_nY || m_nMMPosOffsetX != 0 || m_nMMPosOffsetY != 0 ) &&
					(bool)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_FIRESMM_CLMN ) == true )
				{
					nEmptyIndex = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_EMPTYGRAPHIC_CLMN );
					nGraphicIndex = (long)Game.GetBldStat( nEmptyIndex,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );
				}
				else
				{
					/*if( oIsland.Direction == 1 )
					{
						oValue = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR1GRAPHICINDX_CLMN );
					}
					else if( oIsland.Direction == 2 )
					{
						oValue = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR2GRAPHICINDX_CLMN );
					}
					else if( oIsland.Direction == 3 )
					{
						oValue = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR3GRAPHICINDX_CLMN );
					}

					if( oIsland.Direction == 0 || oValue == null )
					{*/
						nGraphicIndex = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );
					/*}
					else
					{
						nGraphicIndex = (long)oValue;
					}*/
				}
				oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,m_nAnimationFrame,ref sGraphicKey );
			}
			else if( this.SquareStatus == enumSquareStatus.Built && m_bArmed == false )
			{
				oBuilding = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_EMPTYGRAPHIC_CLMN );
				if( oBuilding == null )
				{
					nGraphicIndex = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );
				}
				else
				{
					nEmptyIndex = (long)oBuilding;
					nGraphicIndex = (long)Game.GetBldStat( nEmptyIndex,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );
					oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,m_nAnimationFrame,ref sGraphicKey );
				}
			}
			else if( this.SquareStatus == enumSquareStatus.Destroyed && m_nGobBuildingKey >= 0 )
			{
				nGraphicIndex = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_DIR0GRAPHICINDX_CLMN );

				//Show the destroyed square
				if( m_nStrength >= -30 )
				{
					oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,-1,ref sGraphicKey );
				}
				else if( m_nStrength >= -60 )
				{
					oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,-2,ref sGraphicKey );
				}
				else if( m_nStrength >= -100 )
				{
					oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,-3,ref sGraphicKey );
				}
				else 
				{
					oSrcRect = Game.GetSrcRectForBuildingByGraphicIndex( nGraphicIndex,-4,ref sGraphicKey );
				}
			}


			if( System.Drawing.Rectangle.Empty != oSrcRect && bRender == true )
			{
				oDSGraphicsWrapper.RenderTexture2D( sGraphicKey, oSrcRect, oTrgRect, oClipRect,
													new Vector2( Game.m_cSQRW_BLD / 2,Game.m_cSQRH_BLD / 2 ), 
													0, 0, false,nColorMask );

				//Only render groups if is ours and not destroyed
				if( oIsland.IsMyIsland() == true &&
					(
						this.SquareStatus == enumSquareStatus.Building ||
						this.SquareStatus == enumSquareStatus.Built 
					)
				  )
				{
					//Go through our groups and get the first one
					for( int i=0 ; i<oGroups.Count ; i++ )
					{
						oGroup = (DSSortedList)oGroups.GetByIndex( i );
						//oKey = (Microsoft.DirectX.DirectInput.Key)oGroups.GetKey( i );
						//sGroupNum = DSMisc.KeyToChar( oKey );
						sGroupNum = (string)oGroups.GetKey( i );
						sGroupNum = sGroupNum.Substring( 1,1 );
						if( oGroup.ContainsKey( m_nX.ToString() + "," + m_nY.ToString() ) == true )
						{
							//Render the black shadow background
							oDSGraphicsWrapper.RenderText( oTrgRect.X+10-1,oTrgRect.Y+10-1,System.Drawing.Color.Black,sGroupNum,oClipRect );
							oDSGraphicsWrapper.RenderText( oTrgRect.X+10-1,oTrgRect.Y+10+1,System.Drawing.Color.Black,sGroupNum,oClipRect );
							oDSGraphicsWrapper.RenderText( oTrgRect.X+10+1,oTrgRect.Y+10-1,System.Drawing.Color.Black,sGroupNum,oClipRect );
							oDSGraphicsWrapper.RenderText( oTrgRect.X+10+1,oTrgRect.Y+10+1,System.Drawing.Color.Black,sGroupNum,oClipRect );
							//Now render the number itself
							oDSGraphicsWrapper.RenderText( oTrgRect.X+10,oTrgRect.Y+10,System.Drawing.Color.White,sGroupNum,oClipRect );
							break;
						}
					}
				}
				return( 1 );
			}
			else
			{
				return ( 0 );
			}
		}

		public void RenderScrollingMessage( DSGraphicsWrapper oDSGraphicsWrapper, System.Drawing.Rectangle oTrgRect, 
								    System.Drawing.Rectangle oClipRect, long nSquareW, long nSquareH,
									Island oIsland )
		{
			System.Drawing.Color oBlackColor = System.Drawing.Color.Black;
			System.Drawing.Color oTextColor = System.Drawing.Color.White;
			int nAlpha = 0;
			Vector2 vFontSize = new Vector2( 0,0 );
			double nX = 0;
			double nY = 0;


			if( m_nScrollingMessagePercentDone < 1 )
			{
				if( m_nScrollingMessagePercentDone < .6 )
				{
					nAlpha = 255;
				}
				else
				{
					nAlpha = Convert.ToInt32( 255 * ( 1 - ( ( m_nScrollingMessagePercentDone - .6 ) / .4 ) ) );
				}
				oBlackColor = System.Drawing.Color.FromArgb( nAlpha,0,0,0 );
				oTextColor = System.Drawing.Color.FromArgb( nAlpha,m_oScrollingMessageColor );

				vFontSize = DSResourceManager.GetGlobalInstance().GetFontSize();
				nX = oTrgRect.X + ( nSquareW / 2 ) - ( ( vFontSize.X * m_sScrollingMessage.Length ) / 2 );
				nY = oTrgRect.Y + ( nSquareH / 2 ) - ( m_nScrollingMessagePercentDone * 60 );

				oDSGraphicsWrapper.RenderText( nX-1,nY-1,oBlackColor,m_sScrollingMessage,oClipRect );
				oDSGraphicsWrapper.RenderText( nX-1,nY+1,oBlackColor,m_sScrollingMessage,oClipRect );
				oDSGraphicsWrapper.RenderText( nX+1,nY-1,oBlackColor,m_sScrollingMessage,oClipRect );
				oDSGraphicsWrapper.RenderText( nX+1,nY+1,oBlackColor,m_sScrollingMessage,oClipRect );
				oDSGraphicsWrapper.RenderText( nX,nY,oTextColor,m_sScrollingMessage,oClipRect );
			}
		}


		public void DamageSquare( double nDamage,string sIslandGlobalID,string sDelayTillExplosionDone,bool bIsAntiMatter )
		{
			Island oIsland = null;
			Square oSquare = null;
			Point oEndPoint;
			DSGobTable oTable = null;
			object oValue = null;
			long nGTParent = 0;
			long nDeltaX = 0;
			long nDeltaY = 0;
			long nCenterX = 0;
			long nCenterY = 0;
			bool bFound = false;


			//We can't damage bases from some damage... this may be one of those cases
			if( bIsAntiMatter == false || m_nGobBuildingKey != Game.m_cGOB_BASE_KEY )
			{
				m_nStrength -= nDamage;
			}

			if( m_nStrength <= 0 )
			{
				//If we just destroyed a composite building detonate the rest of them
				if( m_nStatus == enumSquareStatus.Building || m_nStatus == enumSquareStatus.Built )
				{
					oValue = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_GT1SQAR_PRNTBLDKEY_TABLE );
					if( oValue != null && oValue.GetType().ToString() != "System.DBNull" )
					{
						//Identify our parent
						nGTParent = (long)oValue;
						//And identify square 0,0 for this building
						nDeltaX = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAX_TABLE );
						nDeltaY = (long)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAY_TABLE );
						oEndPoint = Game.MoveUpRight( nDeltaX*-1,m_nX,m_nY );
						oEndPoint = Game.MoveUpLeft( nDeltaY,oEndPoint.X,oEndPoint.Y );
						nCenterX = oEndPoint.X;
						nCenterY = oEndPoint.Y;

						//Now walk and find any other peices of this building to destroy
						oTable = Game.GobFile.GetTable( Game.m_cGOB_BLDSTATS_TABLE );
						for( int nRow=0 ; nRow<oTable.RowCount ; nRow++ )
						{
							oValue = oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQAR_PRNTBLDKEY_TABLE,nRow );
							if( oValue != null && oValue.GetType().ToString() != "System.DBNull" )
							{
								if( (long)oValue == nGTParent )
								{
									if( oIsland == null )
									{
										oIsland = m_oGame.GetIsland( sIslandGlobalID );
									}

									bFound = true;

									//Get this changed key
									nDeltaX = (long)oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAX_TABLE,nRow );
									nDeltaY = (long)oTable.GetData( Game.m_cGOB_BLDSTATS_GT1SQR_PRNTDELTAY_TABLE,nRow );
									oEndPoint = Game.MoveUpRight( nDeltaX,nCenterX,nCenterY );
									oEndPoint = Game.MoveUpLeft( nDeltaY*-1,oEndPoint.X,oEndPoint.Y );

									oSquare = oIsland.GetSquare( oEndPoint.X,oEndPoint.Y );
									oSquare.Strength = m_nStrength;

									if( bIsAntiMatter == false )
									{
										m_oGame.AddExplosion( sDelayTillExplosionDone,sIslandGlobalID,oEndPoint.X,oEndPoint.Y,enumExplosionType.Building,bIsAntiMatter,false );
									}
								}
							}
						}
					}
				}

				if( bFound == false )
				{
					//Add our explosion
					if( ( this.SquareStatus == enumSquareStatus.Built || this.SquareStatus == enumSquareStatus.Building ) && bIsAntiMatter == false )
					{
						m_oGame.AddExplosion( sDelayTillExplosionDone,sIslandGlobalID,m_nX,m_nY,enumExplosionType.Building,bIsAntiMatter,true );
					}
					if( this.SquareStatus == enumSquareStatus.Building )
					{
						m_nGobBuildingKey = Game.m_cGOB_UNDRCONSTR_LVL1_KEY;
					}

					//Now if we just destroyed a camo structure then reveal the under building
					if( m_nUnderCamoBuildingKey != Game.m_cCAMO_NOCAMOBUILT &&
						m_nUnderCamoBuildingKey != Game.m_cCAMO_CAMODESTROYED )
					{
						m_nGobBuildingKey = m_nUnderCamoBuildingKey;
						m_nUnderCamoBuildingKey = Game.m_cCAMO_CAMODESTROYED;
						m_nStrength = (double)Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_STRENGTH_CLMN );
					}
					else if( (bool)Game.GetTrnStat( this.SquareType,Game.m_cGOB_TRNSTATS_CANBEDAMAGED_CLMN ) == true )
					{
						this.SquareStatus = enumSquareStatus.Destroyed;
						this.ScarPercent = 1;
					}
				}
			}

			m_bNeedToBeSent = true;
		}

		public void SetSquare( long nGobBuildingKey )
		{
			SetSquare( nGobBuildingKey,false );
		}
		public void SetSquare( long nGobBuildingKey,bool bInstantBuild )
		{
			object oValue = null;


			//Is this a camo unit we are building?
			if( (bool)Game.GetBldStat( nGobBuildingKey,Game.m_cGOB_BLDSTATS_CANCAMO_CLMN ) == true &&
				this.SquareStatus == enumSquareStatus.Built )
			{
				m_nUnderCamoBuildingKey = this.GobBuildingKey;
			}
			else
			{
				m_nUnderCamoBuildingKey = Game.m_cCAMO_NOCAMOBUILT;
			}

			if( bInstantBuild == false )
			{
				this.SquareStatus = enumSquareStatus.Building;
				m_nBuildingProgress = 0;
			}
			else
			{
				this.SquareStatus = enumSquareStatus.Built;
				m_nBuildingProgress = 100;
			}
			m_nGobBuildingKey = nGobBuildingKey;
			m_nAnimationFrame = 0;
			m_bArmed = true;
			m_bNeedToBeSent = true;

			oValue = Game.GetBldStat( Game.m_cGOB_UNDRCONSTR_LVL1_KEY,Game.m_cGOB_BLDSTATS_STRENGTH_CLMN );
			if( oValue != null )
			{
				m_nStrength = (double)oValue;
			}
			else
			{
				m_nStrength = 0;
			}

			oValue = Game.GetBldStat( m_nGobBuildingKey,Game.m_cGOB_BLDSTATS_MMSTRENGTH_CLMN );
			if( oValue != null )
			{
				m_nMMStrength = (double)oValue;
			}
			else
			{
				m_nMMStrength = 0;
			}

			m_nMMX = m_nX;
			m_nMMY = m_nY;
			m_nMMPosOffsetX = 0;
			m_nMMPosOffsetY = 0;

			m_bNeedToBeSent = true;
		}

		public void Bulldoze()
		{
			this.SquareStatus = enumSquareStatus.Empty;
			this.UnderCamoBuildingKey = Game.m_cCAMO_NOCAMOBUILT;
			this.GobBuildingKey = -1;

			if( m_nSoundIndex != -1 )
			{
				if( m_oGame.GameEngine.DirectSound.SoundIsStillPlaying( m_sSoundKey,m_nSoundIndex ) == true )
				{
					m_oGame.GameEngine.DirectSound.StopPlayingSound( m_sSoundKey,m_nSoundIndex );
				}

				m_nSoundIndex = -1;
				m_sSoundKey = "";
				//m_oGame.NumberOfConstructionSoundsPlaying--;					
			}
		}

		private bool CanPlayConstructionSound()
		{
			long nCount = 0;
			long nIndex = -1;
			string sSoundKey = "";


			for( int i=0 ; i<Game.m_cGOB_SOUND_CONSTRUCTION.Length ; i++ )
			{
				nIndex = DSMisc.GetRnd( 0,Game.m_cGOB_SOUND_CONSTRUCTION.Length-1 );
				sSoundKey = Game.m_cGOB_SOUND_CONSTRUCTION[ nIndex ];

				for( int nSndIndex=0 ; nSndIndex<2 ; nSndIndex++ )
				{
					if( m_oGame.GameEngine.DirectSound.SoundIsStillPlaying( sSoundKey,nSndIndex ) == true )
					{
						nCount++;
					}
				}
			}

			return( nCount < 2 );
		}


		public void AddScrollingMessage( string sText,Color cColor )
		{
			m_sScrollingMessage = sText;
			m_nScrollingMessagePercentDone = 0;
			m_oScrollingMessageColor = cColor;
		}

		public string Serialize()
		{
			string sRetVal = "";


			//Now write all the square information
			sRetVal = m_nHeight.ToString() + m_cSQUARE_SEP +
					  Convert.ToInt64( m_nType ).ToString() + m_cSQUARE_SEP +
					  Convert.ToInt64( m_nStatus ).ToString() + m_cSQUARE_SEP +
					  m_nGobBuildingKey.ToString() + m_cSQUARE_SEP + 
					  m_nBuildingProgress.ToString() + m_cSQUARE_SEP + 
					  m_bArmed.ToString() + m_cSQUARE_SEP +  
					  m_nRearmingProgress.ToString() + m_cSQUARE_SEP + 
					  m_nX.ToString() + m_cSQUARE_SEP + 
					  m_nY.ToString() + m_cSQUARE_SEP + 
					  m_nAnimationFrame.ToString() + m_cSQUARE_SEP + 
					  m_nTimeSinceFrameLastChange.ToString() + m_cSQUARE_SEP + 
					  m_nStrength.ToString() + m_cSQUARE_SEP + 
					  m_nMMStrength.ToString() + m_cSQUARE_SEP +
					  m_nMMX.ToString() + m_cSQUARE_SEP + 
					  m_nMMY.ToString() + m_cSQUARE_SEP + 
					  m_nMMPosOffsetX.ToString() + m_cSQUARE_SEP + 
					  m_nMMPosOffsetY.ToString() + m_cSQUARE_SEP + 
					  m_nMMDirection.ToString() + m_cSQUARE_SEP + 
					  m_nMMAnimationCell.ToString() + m_cSQUARE_SEP + 
					  m_nMMTimeSinceAnimationChange.ToString() + m_cSQUARE_SEP + 
					  m_bMMIsOverseas.ToString() + m_cSQUARE_SEP + 
					  m_nUnderCamoBuildingKey.ToString() + m_cSQUARE_SEP + 
					  m_nScarPercent.ToString() + m_cSQUARE_SEP;


			return( sRetVal );
		}
		public void DeSerialize( string sRecord )
		{
			string[] saSquareParamaters = null;

			saSquareParamaters = DSMisc.Split( sRecord,m_cSQUARE_SEP );

			//Now update this island
			m_nHeight				= Convert.ToInt16( saSquareParamaters[ 0 ] );
			m_nType					= (int)Convert.ToInt64( saSquareParamaters[ 1 ] );
			m_nStatus				= (enumSquareStatus)Convert.ToInt64( saSquareParamaters[ 2 ] );
			m_nGobBuildingKey		= Convert.ToInt64( saSquareParamaters[ 3 ] );
			m_nBuildingProgress		= Convert.ToDouble( saSquareParamaters[ 4 ] );
			m_bArmed				= Convert.ToBoolean( saSquareParamaters[ 5 ] );
			m_nRearmingProgress		= Convert.ToDouble( saSquareParamaters[ 6 ] );
			m_nX					= Convert.ToInt16( saSquareParamaters[ 7 ] );
			m_nY					= Convert.ToInt16( saSquareParamaters[ 8 ] );
			m_nAnimationFrame		= Convert.ToInt64( saSquareParamaters[ 9 ] );
			m_nTimeSinceFrameLastChange = Convert.ToDouble( saSquareParamaters[ 10 ] );
			m_nStrength				= Convert.ToDouble( saSquareParamaters[ 11 ] );
			m_nMMStrength			= Convert.ToDouble( saSquareParamaters[ 12 ] );
			m_nMMX					= Convert.ToInt64( saSquareParamaters[ 13 ] );
			m_nMMY					= Convert.ToInt64( saSquareParamaters[ 14 ] );
			m_nMMPosOffsetX			= Convert.ToDouble( saSquareParamaters[ 15 ] );
			m_nMMPosOffsetY			= Convert.ToDouble( saSquareParamaters[ 16 ] );
			m_nMMDirection			= Convert.ToInt64( saSquareParamaters[ 17 ] );
			m_nMMAnimationCell		= Convert.ToInt64( saSquareParamaters[ 18 ] );
			m_nMMTimeSinceAnimationChange = Convert.ToDouble( saSquareParamaters[ 19 ] );
			m_bMMIsOverseas			= Convert.ToBoolean( saSquareParamaters[ 20 ] );
			m_nUnderCamoBuildingKey	= Convert.ToInt64( saSquareParamaters[ 21 ] );

			if( saSquareParamaters.Length > 23 )
			{
				m_nScarPercent = Convert.ToDouble( saSquareParamaters[ 22 ] );
			}
		}



		#region Properties
		public int SquareType
		{
			get
			{
				return( m_nType );
			}
			set
			{
				m_nType = value;
			}
		}
		public enumSquareStatus SquareStatus
		{
			get
			{
				return( m_nStatus );
			}
			set
			{
				if( value == enumSquareStatus.Empty )
				{
					m_bNeedToBeSent = true;
				}
				m_nStatus = value;
			}
		}
		public long Height
		{
			get
			{
				return( m_nHeight );
			}
			set
			{
				m_nHeight = value;
			}
		}
		public long GobBuildingKey
		{
			get
			{
				return( m_nGobBuildingKey );
			}
			set
			{
				m_nGobBuildingKey = value;
			}
		}
		public double PercentBuildingComplete
		{
			get
			{
				return( m_nBuildingProgress );
			}
			set
			{
				m_nBuildingProgress = value;
			}
		}
		public long X
		{
			get
			{
				return( m_nX );
			}
			set
			{
				m_nX = value;
			}
		}
		public long Y
		{
			get
			{
				return( m_nY );
			}
			set
			{
				m_nY = value;
			}
		}
		public bool Armed
		{
			get
			{
				return( m_bArmed );
			}
			set
			{
				m_bArmed = value;
			}
		}
		public bool NeedToBeSent
		{
			get
			{
				return( m_bNeedToBeSent);
			}
			set
			{
				m_bNeedToBeSent = value;
			}
		}
		public double Strength
		{
			get
			{
				return( m_nStrength );
			}
			set
			{
				m_nStrength = value;
			}
		}
		public double MMStrength
		{
			get
			{
				return( m_nMMStrength );
			}
			set
			{
				m_nMMStrength = value;
			}
		}
		public Game Game
		{
			get
			{
				return( m_oGame );
			}
		}

		public long MMX
		{
			get
			{
				return( m_nMMX);
			}
			set
			{
				m_nMMX = value;
			}
		}
		public long MMY
		{
			get
			{
				return( m_nMMY );
			}
			set
			{
				m_nMMY = value;
			}
		}
		public double MMPosOffsetX
		{
			get
			{
				return( m_nMMPosOffsetX );
			}
			set
			{
				m_nMMPosOffsetX = value;
			}
		}
		public double MMPosOffsetY
		{
			get
			{
				return( m_nMMPosOffsetY );
			}
			set
			{
				m_nMMPosOffsetY = value;
			}
		}
		public long MMDirection
		{
			get
			{
				return( m_nMMDirection );
			}
			set
			{
				m_nMMDirection = value;
			}
		}
		public bool MMFiring
		{
			get
			{
				return( m_bMMFiring );
			}
			set
			{
				m_bMMFiring = value;
			}
		}
		public long MMAnimationCell
		{
			get
			{
				return( m_nMMAnimationCell );
			}
			set
			{
				m_nMMAnimationCell = value;
			}
		}
		public double MMTimeSinceAnimationChange
		{
			get
			{
				return( m_nMMTimeSinceAnimationChange );
			}
			set
			{
				m_nMMTimeSinceAnimationChange = value;
			}
		}
		public long MMGraphicIndex
		{
			get
			{
				return( (long)Game.GetBldStat( this.GobBuildingKey,Game.m_cGOB_BLDSTATS_MMGRAPHICINDEX_CLMN ) );
			}
		}
		public bool MMIsOverseas
		{
			get
			{
				return( m_bMMIsOverseas );
			}
			set
			{
				m_bMMIsOverseas = value;
			}
		}
		public long UnderCamoBuildingKey
		{
			get
			{
				return( m_nUnderCamoBuildingKey );
			}
			set
			{
				m_nUnderCamoBuildingKey = value;
			}
		}
		public int SoundIndex
		{
			get
			{
				return( m_nSoundIndex );
			}
			set
			{
				m_nSoundIndex = value;
			}
		}
		public string SoundKey
		{
			get
			{
				return( m_sSoundKey );
			}
			set
			{
				m_sSoundKey = value;
			}
		}
		public double ScarPercent
		{
			get
			{
				return( m_nScarPercent );
			}
			set
			{
				m_nScarPercent = value;
			}
		}
		public bool DefenseHasFiredAtMMThisRound
		{
			get
			{
				return( m_bDefenseHasFiredAtMMThisRound );
			}
			set
			{
				m_bDefenseHasFiredAtMMThisRound = value;
			}
		}
		#endregion
	}
}
