/*
	 * 分析位置 包含座標及位置物件
	 * parse 
	 * <Position3D x="x" y="y" z="z" />
	 * <Position3D objectName="objectName" />
	 */
	public static bool ParsePosition( XmlNode _PositionNode , 
									  ref PosAnchor _PosAnchor )
	{
		if( "Position3D" == _PositionNode.Name )
		{
			if( null != _PositionNode.Attributes[ "objectName" ] )
			{
				string objectName = _PositionNode.Attributes[ "objectName" ].Value ;
				_PosAnchor.Setup( objectName ) ;
			}
			else
			{
				
				// 絕對座標
				string strx = _PositionNode.Attributes[ "x" ].Value ;
				string stry = _PositionNode.Attributes[ "y" ].Value ;
				string strz = _PositionNode.Attributes[ "z" ].Value ;
				float x , y , z ;
				float.TryParse( strx , out x ) ;
				float.TryParse( stry , out y ) ;
				float.TryParse( strz , out z ) ;
				Vector3 setPosition = new Vector3( x , y , z ) ;
				_PosAnchor.Setup( setPosition ) ;
			}			

			return true ;
		}
		return false ;
	}
 public PosRoute( PosRoute _src )
 {
     m_Destination = new PosAnchor( _src.m_Destination ) ;
     m_MoveTime = _src.m_MoveTime ;
     m_WaitTime = _src.m_WaitTime ;
     if( null != _src.m_MoveDetectGUIObject )
         m_MoveDetectGUIObject = new NamedObject( _src.m_MoveDetectGUIObject ) ;
     if( null != _src.m_WaitDetectGUIObject )
         m_WaitDetectGUIObject = new NamedObject( _src.m_WaitDetectGUIObject ) ;
 }
	/*
	 * parse 
	 * <xxx PosAnchor="x,y,z" />
	 * <xxx PosAnchor="objectName" />
	 */
	public static bool ParseAnchor( XmlNode _Node , 
									ref PosAnchor _ResultAnchor )
	{
		if( null == _Node.Attributes[ "PosAnchor" ] )
			return false ;
		string PosAnchorStr = _Node.Attributes[ "PosAnchor" ].Value ;
			
		return ParseAnchor( PosAnchorStr , 
							ref _ResultAnchor ) ;
	}		
	public static bool ParseAnchor( string _AnchorStr , 
									ref PosAnchor _ResultAnchor )
	{
		char [] seperator = {','} ;
		string[] strVec = _AnchorStr.Split( seperator ) ;
		if( strVec.Length > 2 )
		{
			float x = 0 ;
			float y = 0 ;
			float z = 0 ;
			ParsePosition( _AnchorStr , ref x , ref y , ref z ) ;
			_ResultAnchor.Setup( new Vector3( x , y , z ) ) ;
			return true ;
		}
		else
		{
			_ResultAnchor.Setup( _AnchorStr ) ;
			return true ;
		}		
	}	
	public static bool ParseUnit( 
	                                      #if USE_XML
	                                      XmlNode _node ,
	                                      #endif // USE_XML
	                             ref string _UnitName , 
	                             ref string _PrefabeName ,
	                             ref string _UnitDataTemplateName ,
	                             ref PosAnchor _PosAnchor , 
	                             ref Quaternion _Orientation ,
	                             ref Dictionary<string , StandardParameter> _StandardParamMap )
	{
		#if USE_XML
		bool ret = XMLParseLevelUtility.ParseUnit( _node , 
		                                          ref  _UnitName , 
		                                          ref _PrefabeName ,
		                                          ref _UnitDataTemplateName ,
		                                          ref _PosAnchor , 
		                                          ref _Orientation ,
		                                          ref _StandardParamMap ) ;
		
		
		return ret ;
		#endif // USE_XML
	}
	// 分析靜態物件
	private static void ParseStaticObjectAtt( XmlNode _UnitNode , 
	                                     ref string _UnitName ,
	                                     ref string _PrefabName ,
	                                     ref Vector3 _InitPosition ,
	                                     ref Quaternion _InitQuaternion )	
	{
		if( null != _UnitNode.Attributes[ "Name" ] )
			_UnitName = _UnitNode.Attributes[ "Name" ].Value ;
		if( null != _UnitNode.Attributes[ "PrefabName" ] )
			_PrefabName = _UnitNode.Attributes[ "PrefabName" ].Value ;
		
		if( true == _UnitNode.HasChildNodes )
		{
			for( int j = 0 ; j < _UnitNode.ChildNodes.Count ; ++j )
			{
				PosAnchor posAnchor = new PosAnchor() ;
				if( true == ParsePosition( _UnitNode.ChildNodes[ j ] , 
				                          ref posAnchor ) )
				{
					_InitPosition = posAnchor.GetPosition() ;
				}
				else if( true == ParseQuaternion( _UnitNode.ChildNodes[ j ] , 
				                                 ref _InitQuaternion ) )
				{
					
				}				
			}
		}
	}
 public UnitInitializationData( UnitInitializationData _src )
 {
     unitName = _src.unitName ;
     prefabName = _src.prefabName ;
     unitDataTemplateName = _src.unitDataTemplateName ;
     raceName = _src.raceName ;
     sideName = _src.sideName ;
     initPosition = _src.initPosition ;
     initOrientation = _src.initOrientation ;
     supplementalVec = _src.supplementalVec ;
 }
    /* Parse Unit Init Data */
    public static bool ParseUnit( XmlNode _UnitNode , 
								  out string _UnitName , 
								  out string _TemplateName ,
								  out string _UnitDataTemplateName ,
								  out string _RaceName ,
								  out string _SideName ,
							      out PosAnchor _PosAnchor , 
							      out Quaternion _Orientation ,
								  out Dictionary<string , string> _SupplementalVec )
    {
        _UnitName = "" ;
        _TemplateName = "" ;
        _UnitDataTemplateName = "" ;
        _RaceName = "" ;
        _SideName = "" ;
        _PosAnchor = new PosAnchor() ;
        _Orientation = Quaternion.identity ;
        _SupplementalVec = new Dictionary<string , string>() ;

        if( "Unit" != _UnitNode.Name )
        {
            // Debug.Log( "ParseUnitInitData() : Unit != _UnitNode.Name:" + _UnitNode.Name ) ;
            return false ;
        }

        return ParseUnitInitData( _UnitNode ,
                                  ref _UnitName ,
                                  ref _TemplateName ,
                                  ref _UnitDataTemplateName ,
                                  ref _RaceName ,
                                  ref _SideName ,
                                  ref _PosAnchor ,
                                  ref _Orientation ,
                                  ref _SupplementalVec ) ;
    }
    public override bool ParseXML( XmlNode _Node )
    {
        #if DEBUG
        Debug.Log( "MoveObjectPositionConditionEvent::ParseXML()" ) ;
        #endif
        PosAnchor posAnchor = new PosAnchor() ;
        for( int i = 0 ; i < _Node.ChildNodes.Count ; ++i )
        {
            if( true == base.ParseXML( _Node.ChildNodes[ i ] ) )
            {

            }
            else if( true == XMLParseLevelUtility.ParsePosition( _Node.ChildNodes[ i ] ,
                                                                 ref posAnchor ) )
            {
                m_MoveToPosition = posAnchor.GetPosition() ;
            }
        }

        if( null == _Node.Attributes["ObjectName"] )
        {
            return false ;
        }

        m_TargetObject.Setup( _Node.Attributes["ObjectName"].Value , null );

        return true ;
    }
	public PosAnchor( PosAnchor _src )
	{	
		m_UseObject = _src.m_UseObject ;
		m_Position = _src.m_Position ;
		m_GameObject = _src.m_GameObject ;
	}
	public void LoadLevel( string _LevelFilepath )
	{
		Dictionary<string,UnitDataSetting> unitDataSettingTable = GlobalSingleton.GetUnitDataSettingTable() ;
		Dictionary<string,UnitDataStruct> unitDataStructTable = GlobalSingleton.GetUnitDataStructTable() ;

		Debug.Log( "LoadLevel(), _LevelFilepath=" + _LevelFilepath ) ;
		if( 0 == _LevelFilepath.Length )
		{
			// warning
			Debug.LogWarning( "_LevelFilepath=" + _LevelFilepath ) ;
			return ;
		}

		TextAsset ta = Resources.Load<TextAsset>( _LevelFilepath );
		if( null == ta )
		{
			Debug.LogError( "LoadLevel() null == ta" ) ;
			return ;
		}
#if USE_XML
		XmlDocument doc = new XmlDocument() ;
		doc.LoadXml( ta.text ) ;
		XmlNode root = doc.FirstChild ;

		if( null == root )
		{
			Debug.LogError( "LoadLevel() : null == root" ) ;
			return ;
		}
		
		// string levelname = root.Attributes[ "name" ].Value ;
		if( false == root.HasChildNodes )
		{
			Debug.Log( "LoadLevel() : false == root.HasChildNodes" ) ;
			return ;			
		}
#endif // USE_XML

#if USE_XML
		for( int i = 0 ; i < root.ChildNodes.Count ; ++i )
		{
			XmlNode unitNode = root.ChildNodes[ i ] ;
#endif // USE_XML
			string unitName = "";
			string prefabTemplateName = "";
			string unitDataTemplateName = "";

			Vector3 position = Vector3.zero ;
			PosAnchor posAnchor = new PosAnchor() ;
			Quaternion orientation = new Quaternion() ;
			string textureName = "";
			Dictionary<string,StandardParameter> standardParamMap = new Dictionary<string, StandardParameter>();
			string defensePropertyStr = "" ;

			// Debug.Log( "LoadLevel() : unitNode.Name=" + unitNode.Name ) ;
			
			if( -1 != unitNode.Name.IndexOf( "comment" ) )
			{
				// comment
			}


			else if( true == ParseUtility.ParseUnit( unitNode,
			                                        ref unitName ,
				                                                ref prefabTemplateName , 
			                                        ref unitDataTemplateName ,
			                                        ref posAnchor , 
				                                                ref orientation ,
			                                        ref standardParamMap ) )
			{
				GameObject obj = PrefabInstantiate.CreateByInit( prefabTemplateName , 
				                                                unitName , 
				                                                posAnchor.GetPosition() , 
				                                                orientation ) ;

				UnitData unitData = null ;
				if( 0 != unitDataTemplateName.Length &&
				   true == unitDataSettingTable.ContainsKey( unitDataTemplateName ) )
				{
					// Debug.Log( "unitDataTemplateName=" + unitDataTemplateName ) ;
					unitData = obj.AddComponent<UnitData>() ;

					UnitDataStruct unitDataStruct = new UnitDataStruct() ;
					unitDataStructTable.Add( obj.name , unitDataStruct ) ;// 掛上 global singleton

					unitDataStruct.Import( unitDataSettingTable[ unitDataTemplateName ] ) ;// data setting 共用

					unitData.m_UnitDataStruct = unitDataStruct ;
				}

				if( null != unitData )
				{
					unitData.m_UnitDataStruct.ImportStandardParameter( standardParamMap ) ;
				}

//				Debug.Log( "ParseUtility.ParseUnit , unitData.m_UnitDataStruct.standardParameters.Count=" + unitData.m_UnitDataStruct.standardParameters.Count ) ;
//				foreach( string key in unitData.m_UnitDataStruct.standardParameters.Keys )
//				{
//					Debug.Log( "key=" + key ) ;
//				}

			}
			else if( true == ParseUtility.ParseStaticObject( unitNode,
			                                                 ref unitName ,
			                                                 ref prefabTemplateName , 
			                                                 ref position , 
			                                                 ref orientation  ) )
			{
				/*GameObject obj =*/ PrefabInstantiate.CreateByInit( prefabTemplateName , 
				                                                unitName , 
				                                                position , 
				                                                orientation ) ;
			}
			else if( true == ParseUtility.ParseMapZoneObject( unitNode,
		                                                     ref unitName ,
		                                                     ref prefabTemplateName , 
		                                                     ref position , 
		                                                     ref orientation , 
			                                                 ref textureName ) )
			{
				GameObject obj = PrefabInstantiate.CreateByInit( prefabTemplateName , 
				                                                unitName , 
				                                                position , 
				                                                orientation ) ;

				if( 0 != textureName.Length )
				{
					obj.GetComponent<Renderer>().material = new Material( obj.GetComponent<Renderer>().material ) ;
					Texture tex = ResourceLoad.LoadTexture( textureName ) ;
					if( null == tex )
					{

					}
					else
					{
						obj.GetComponent<Renderer>().material.mainTexture = tex ;
					}
				}
			}
			else if( true == ParseUtility.ParseExistUnit( unitNode,
			                                        ref unitName ,
			                                        ref unitDataTemplateName ) )
			{
				GameObject obj = GameObject.Find( unitName ) ;
				UnitData unitData = null ;
				if( null != obj &&
				   0 != unitDataTemplateName.Length &&
				   true == unitDataSettingTable.ContainsKey( unitDataTemplateName ) )
				{
					// Debug.Log( "unitDataTemplateName=" + unitDataTemplateName ) ;
					unitData = obj.AddComponent<UnitData>() ;
					
					UnitDataStruct unitDataStruct = new UnitDataStruct() ;
					unitDataStructTable.Add( obj.name , unitDataStruct ) ;// 掛上 global singleton
					
					unitDataStruct.Import( unitDataSettingTable[ unitDataTemplateName ] ) ;// data setting 共用
					
					unitData.m_UnitDataStruct = unitDataStruct ;
				}

				
				Debug.Log( "ParseUtility.ParseExistUnit , unitData.m_UnitDataStruct.standardParameters.Count=" + unitData.m_UnitDataStruct.standardParameters.Count ) ;
			}
			else if( true == ParseUtility.ParseUnitDataStruct( unitNode,
			                                             ref unitName ,
			                                             ref unitDataTemplateName ,
			                                             ref defensePropertyStr ) )
			{
				if( 0 != unitDataTemplateName.Length &&
				   true == unitDataSettingTable.ContainsKey( unitDataTemplateName ) )
				{
					Debug.Log( "LoadLevel(), UnitDataStruct=" + unitDataTemplateName ) ;
					UnitDataStruct unitDataStruct = new UnitDataStruct() ;
					unitDataStruct.Import( unitDataSettingTable[ unitDataTemplateName ] ) ;// data setting 共用
					
					Debug.Log( "LoadLevel(), UnitDataStruct defensePropertyStr=" + defensePropertyStr ) ;
					unitDataStruct.DefenseProperty.Parse( defensePropertyStr ) ;
					
					if( false == unitDataStructTable.ContainsKey( unitName ) )
					{
						unitDataStructTable.Add( unitName , unitDataStruct ) ;// 掛上 global singleton
					}
					else
					{
						unitDataStructTable[ unitName ] = unitDataStruct ;// 掛上 global singleton
					}
				}
			}
#if USE_XML
		}
#endif // USE_XML			

	}
    public UnitGenerationData( string _UnitName , 
								string _PrefabTemplateName ,
								string _UnitDataTemplateName ,
								string _RaceName ,
								string _SideName ,
								PosAnchor _InitPosition , 
								Quaternion _InitOrientation ,
								Dictionary<string , string > _SupplementalVec ,
								float _time )
        : base(_UnitName , 
														_PrefabTemplateName ,
														_UnitDataTemplateName ,
														_RaceName ,
														_SideName ,
														_InitPosition , 
														_InitOrientation ,
														_SupplementalVec)
    {
        time = _time ;
    }
    public UnitInitializationData( string _UnitName , 
								   string _PrefabTemplateName ,
								   string _UnitDataTemplateName ,
								   string _RaceName ,
								   string _SideName ,
								   PosAnchor _InitPosition , 
								   Quaternion _InitOrientation ,
								   Dictionary<string , string > _SupplementalVec )
    {
        unitName = _UnitName ;
        prefabName = _PrefabTemplateName ;
        unitDataTemplateName = _UnitDataTemplateName ;
        raceName = _RaceName ;
        sideName = _SideName ;
        initPosition = _InitPosition ;
        initOrientation = _InitOrientation ;
        supplementalVec = _SupplementalVec ;
    }
    // 分析動態產生單位資料
    public static bool ParseEnemyGeneration( XmlNode _UnitNode , 
										   out string _UnitName , 
										   out string _TemplateName ,
										   out string _UnitDataTemplateName ,
										   out string _RaceName ,
										   out string _SideName ,
										   out PosAnchor _PosAnchor , 
										   out Quaternion _Orientation ,
										   out Dictionary<string , string> _SupplementalVec ,
										   out float _time )
    {
        _UnitName = "" ;
        _TemplateName = "" ;
        _UnitDataTemplateName = "" ;
        _RaceName = "" ;
        _SideName = "" ;
        _PosAnchor = new PosAnchor() ;
        _Orientation = Quaternion.identity ;
        _time = 0.0f ;
        _SupplementalVec = new Dictionary<string, string>() ;

        if( "EnemyGeneration" != _UnitNode.Name )
        {
            // Debug.Log( "ParseEnemyGeneration() : Unit != _UnitNode.Name:" + _UnitNode.Name ) ;
            return false ;
        }

        if( null != _UnitNode.Attributes["time"] )
        {
            string timestr = _UnitNode.Attributes["time"].Value ;
            float time = 0.0f ;
            float.TryParse( timestr , out time ) ;
            _time = time ;
        }

        return ParseUnitInitData( _UnitNode ,
                                  ref _UnitName ,
                                  ref _TemplateName ,
                                  ref _UnitDataTemplateName ,
                                  ref _RaceName ,
                                  ref _SideName ,
                                  ref _PosAnchor ,
                                  ref _Orientation ,
                                  ref _SupplementalVec ) ;
    }
	public static bool ParseUnitAtt( XmlNode _UnitNode , 
									  ref string _UnitName , 
									  ref string _PrefabeName ,
	                                ref string _UnitDataTemplateName ,
									  ref PosAnchor _PosAnchor , 
									  ref Quaternion _Orientation ,
	                                ref Dictionary<string,StandardParameter> _StandardParamMap )
	{
		if( null != _UnitNode.Attributes[ "Name" ] )
			_UnitName = _UnitNode.Attributes[ "Name" ].Value ;
		
		if( null != _UnitNode.Attributes[ "PrefabName" ] )
			_PrefabeName = _UnitNode.Attributes[ "PrefabName" ].Value ;

		if( null != _UnitNode.Attributes[ "UnitDataTemplateName" ] )
			_UnitDataTemplateName = _UnitNode.Attributes[ "UnitDataTemplateName" ].Value ;

		
		if( true == _UnitNode.HasChildNodes )
		{
			for( int j = 0 ; j < _UnitNode.ChildNodes.Count ; ++j )
			{
				if( true == ParsePosition( _UnitNode.ChildNodes[ j ] , 
										   ref _PosAnchor ) )
				{
					
				}
				else if( true == ParseQuaternion( _UnitNode.ChildNodes[ j ] , 
																	   ref _Orientation ) )
				{
					
				}
				else if( true == ParseStandardParameterMap( _UnitNode.ChildNodes[ j ] , 
				                                           ref _StandardParamMap ) )
				{
					
				}
			}
		}
		return true ;
	}
    // 分析靜態物件
    public static bool ParseStaticObject( XmlNode _UnitNode , 
										ref string _UnitName ,
										ref string _PrefabName ,
										ref Vector3 _InitPosition ,
										ref Quaternion _InitQuaternion )
    {
        if( "StaticObject" == _UnitNode.Name )
        {
            if( null != _UnitNode.Attributes[ "name" ] )
                _UnitName = _UnitNode.Attributes[ "name" ].Value ;
            if( null != _UnitNode.Attributes[ "PrefabName" ] )
                _PrefabName = _UnitNode.Attributes[ "PrefabName" ].Value ;

            if( true == _UnitNode.HasChildNodes )
            {
                for( int j = 0 ; j < _UnitNode.ChildNodes.Count ; ++j )
                {
                    PosAnchor posAnchor = new PosAnchor() ;
                    if( true == ParsePosition( _UnitNode.ChildNodes[ j ] ,
                                              	ref posAnchor ) )
                    {
                        _InitPosition = posAnchor.GetPosition() ;
                        // Debug.Log( "_InitPosition=" + _InitPosition ) ;
                    }
                    else if( true == ParseQuaternion( _UnitNode.ChildNodes[ j ] ,
                                                       ref _InitQuaternion ) )
                    {

                    }
                }
            }
            return true ;
        }
        return false ;
    }
	/* Parse Unit Init Data */
	public static bool ParseUnit( XmlNode _UnitNode , 
								  ref string _UnitName , 
	                             ref string _PrefabeName ,
	                             ref string _UnitDataTemplateName ,
	                             ref PosAnchor _PosAnchor , 
	                             ref Quaternion _Orientation ,
	                             ref Dictionary<string,StandardParameter> _StandardParamMap )
	{
		_UnitName = "" ;
		_PrefabeName = "" ;
		_PosAnchor = new PosAnchor() ;
		_Orientation = Quaternion.identity ;

		if( "Unit" != _UnitNode.Name )
		{
			// Debug.Log( "ParseUnitInitData() : Unit != _UnitNode.Name:" + _UnitNode.Name ) ;
			return false ;
		}
		
		return ParseUnitAtt( _UnitNode , 
								  ref _UnitName , 
		                    ref _PrefabeName ,
		                    ref _UnitDataTemplateName ,
								  ref _PosAnchor , 
								  ref _Orientation ,
		                    ref _StandardParamMap ) ;
	}
    // 分析XML 取出每筆單位的資料
    public static bool ParseUnitInitData( XmlNode _UnitNode , 
										  ref string _UnitName , 
										  ref string _TemplateName ,
										  ref string _UnitDataTemplateName ,
										  ref string _RaceName ,
										  ref string _SideName ,		
										  ref PosAnchor _PosAnchor , 
										  ref Quaternion _Orientation ,
										  ref Dictionary<string , string> _SupplementalVec )
    {
        if( null != _UnitNode.Attributes[ "name" ] )
            _UnitName = _UnitNode.Attributes[ "name" ].Value ;

        if( null != _UnitNode.Attributes[ "PrefabName" ] )
            _TemplateName = _UnitNode.Attributes[ "PrefabName" ].Value ;

        if( null != _UnitNode.Attributes[ "unitDataTemplateName" ] )
            _UnitDataTemplateName = _UnitNode.Attributes[ "unitDataTemplateName" ].Value ;

        if( null != _UnitNode.Attributes[ "raceName" ] )
            _RaceName = _UnitNode.Attributes[ "raceName" ].Value ;

        if( null != _UnitNode.Attributes[ "sideName" ] )
            _SideName = _UnitNode.Attributes[ "sideName" ].Value ;

        string Label ;
        string Value ;

        if( true == _UnitNode.HasChildNodes )
        {
            for( int j = 0 ; j < _UnitNode.ChildNodes.Count ; ++j )
            {
                if( true == ParsePosition( _UnitNode.ChildNodes[ j ] ,
                                           ref _PosAnchor ) )
                {

                }
                else if( true == ParseQuaternion( _UnitNode.ChildNodes[ j ] ,
                                                                       ref _Orientation ) )
                {

                }
                else if( true == ParseSupplementalPair( _UnitNode.ChildNodes[ j ] ,
                                                                             out Label ,
                                                                             out Value ) )
                {
                    // Debug.Log( "ParseSupplementalPair() " + Label + " " + Value ) ;
                    _SupplementalVec.Add( Label , Value ) ;
                }
            }
        }
        return true ;
    }
 public Condition_Collision( Condition_Collision _src )
 {
     m_TestObject = new NamedObject( _src.m_TestObject ) ;
     m_TestObjects = new List<NamedObject>( _src.m_TestObjects ) ;
     m_PosAnchor = new PosAnchor( _src.m_PosAnchor ) ;
     m_JudgeDistance = _src.m_JudgeDistance ;
 }