void ApplyProductionRule(ECS_Entity thisEntity, LSystemRule rule)
    {
        //1. Create new blank string
        //2. for each char in old sting check if rule applies
        //3.if rule applies then add rule.output to new string.
        //4. if rule does not apply then add old char to new string



        //Add new version of the whole string
        thisEntity.lSysComp.CycleStep += 1;
        thisEntity.lSysComp.DNA.Add("");


        //Debug.Log("CycleStep : " + thisEntity.lSysComp.CycleStep + "DNA.Count : " + thisEntity.lSysComp.DNA[thisEntity.lSysComp.DNA.Count] );


        for (int charIndex = 0; charIndex < thisEntity.lSysComp.DNA [thisEntity.lSysComp.CycleStep - 1].Length; charIndex++)
        {
            if (thisEntity.lSysComp.DNA [thisEntity.lSysComp.CycleStep - 1] [charIndex].ToString() == rule.Input)
            {
                thisEntity.lSysComp.DNA [thisEntity.lSysComp.CycleStep] += rule.Output;
            }
            else
            {
                thisEntity.lSysComp.DNA [thisEntity.lSysComp.CycleStep] += (thisEntity.lSysComp.DNA [thisEntity.lSysComp.CycleStep - 1] [charIndex].ToString());
            }
        }
    }
 public void randomiseEntityMovStats(ECS_Entity thisEntity)
 {
     if (thisEntity.movComp != null)
     {
         thisEntity.movComp.maxInertia *= Random.Range(0.9f, 1.1f);
         thisEntity.movComp.agility    *= Random.Range(0.9f, 1.1f);
     }
 }
    IEnumerator CycleLoop(int entityId, ECS_Entity thisEntity)
    {
        while (thisEntity != null && thisEntity.lSysComp.NeedsGenerating == true && thisEntity.lSysComp.IsGenerating == true)
        {
            yield return(new WaitForSeconds(thisEntity.lSysComp.CycleTime + (entityId / 10)));

            Iterate(entityId, thisEntity);
        }
    }
    public void AddToEntityPool(FactoryInstruction thisTemp, Vector2 spawnPoint)
    {
        ECS_Entity thisEntity = (ECS_Entity)Instantiate(thisTemp.entity);

        entityPool.Entities.Add(thisEntity);
        thisEntity.posComp.position = spawnPoint;
        randomiseEntityMovStats(thisEntity);

        InstantiateGameObjectAndInitialise(thisEntity);
    }
    void InitialiseThisEntity(int entityId, ECS_Entity thisEntity)
    {
        if (((thisEntity.lSysComp) != null))
        {
            thisEntity.lSysComp.CycleStep = 0;
            thisEntity.lSysComp.DNA[0]    = thisEntity.lSysComp.Axiom.Axiom;
            thisEntity.lSysComp.DNACycle  = 0;


            thisEntity.lSysComp.IsGenerating = true;
            Debug.Log("lSysComp.IsGenerating : " + thisEntity.lSysComp.IsGenerating);
        }
    }
    private void InstantiateGameObjectAndInitialise(ECS_Entity thisEntity)
    {
        InstantiateComponentsAndInitialise(thisEntity);

        thisEntity.gameObj = (GameObject)Instantiate(thisEntity.gameObj);
        thisEntity.gameObj.transform.parent   = entityPool.gameObject.transform;
        thisEntity.gameObj.transform.position = thisEntity.posComp.position;
        thisEntity.trans = thisEntity.gameObj.transform;


        EntityLink myEntityLink = thisEntity.gameObj.AddComponent <EntityLink> ();

        myEntityLink.myEntity = thisEntity;
    }
 public CellDNA InstantiateInstructionInList(ECS_Entity thisEntity, List <CellDNA> thisInstructionList, int thisCycle)
 {
     if (thisCycle == 0)
     {
         thisInstructionList.Clear();
         thisInstructionList.Add(Instantiate(thisEntity.lSysFacComp.InstructionStack.Peek()));
     }
     else
     {
         thisInstructionList.Add(Instantiate(thisEntity.lSysFacComp.InstructionList[thisCycle - 1]));
     }
     thisInstructionList [thisCycle].name = "Instruction";
     return(thisInstructionList [thisCycle]);
 }
    void InitialiseThisEntity(int entityId, ECS_Entity thisEntity)
    {
        Debug.Log("fac axiom: " + thisEntity.lSysFacComp.FactoryAxiom);
        thisEntity.lSysFacComp.FactoryAxiom          = Instantiate(thisEntity.lSysFacComp.FactoryAxiom);
        thisEntity.lSysFacComp.FactoryAxiom.position = thisEntity.posComp.position;
        thisEntity.lSysFacComp.FactoryAxiom.Angle    = (float)GetRandomDouble(random, 0, 360);
        Debug.Log("fac axiom prepush: " + thisEntity.lSysFacComp.FactoryAxiom);

        thisEntity.lSysFacComp.InstructionStack.Push(thisEntity.lSysFacComp.FactoryAxiom);
        Debug.Log("fac axiom post push : " + thisEntity.lSysFacComp.FactoryAxiom);

        thisEntity.lSysFacComp.CycleStep = 0;
        thisEntity.lSysFacComp.MaxCycle  = thisEntity.lSysComp.DNA[thisEntity.lSysComp.DNA.Count - 1].Length;
        thisEntity.lSysFacComp.IsDrawing = true;
    }
    //find entities with components for this role
    void Iterate(int entityId, ECS_Entity thisEntity)
    {
        if (thisEntity.lSysComp.CycleStep >= thisEntity.lSysComp.MaxCycle)
        {
            thisEntity.lSysComp.NeedsGenerating = false;
            thisEntity.lSysComp.IsGenerating    = false;
            thisEntity.lSysComp.NeedsDrawing    = true;
            return;
        }



        for (int rule = 0; rule < thisEntity.lSysComp.Rules.Length; rule++)
        {
            {
                ApplyProductionRule(thisEntity, thisEntity.lSysComp.Rules[rule]);
            }
        }
    }
    private void InstantiateComponentsAndInitialise(ECS_Entity thisEntity)
    {
        if (thisEntity.posComp != null)
        {
            thisEntity.posComp = (PositionComponent)Instantiate(thisEntity.posComp);
        }

        if (thisEntity.movComp != null)
        {
            thisEntity.movComp = (MovementComponent)Instantiate(thisEntity.movComp);
        }
        if (thisEntity.mouseInputComp != null)
        {
            thisEntity.mouseInputComp = (MouseInputComponent)Instantiate(thisEntity.mouseInputComp);
        }
        if (thisEntity.keyInputComp != null)
        {
            thisEntity.keyInputComp = (KeyboardInputComponent)Instantiate(thisEntity.keyInputComp);
        }
        if (thisEntity.navWaypointComp != null)
        {
            thisEntity.navWaypointComp = (NavigationWaypointComponent)Instantiate(thisEntity.navWaypointComp);
        }
        if (thisEntity.factoryComp != null)
        {
            thisEntity.factoryComp = (FactoryComponent)Instantiate(thisEntity.factoryComp);
        }
        if (thisEntity.lSysComp != null)
        {
            thisEntity.lSysComp = (LSystemComponent)Instantiate(thisEntity.lSysComp);
        }
        if (thisEntity.lSysFacComp != null)
        {
            thisEntity.lSysFacComp = (LSystemFactoryComponent)Instantiate(thisEntity.lSysFacComp);
        }
    }
    void StartCycleAndInitialise(int entityId, ECS_Entity thisEntity)
    {
        InitialiseThisEntity(entityId, thisEntity);

        StartCoroutine(CycleLoop(entityId, thisEntity));
    }
    //iterate through all entities that have correct components
    void Iterate(int entityId, ECS_Entity thisEntity)
    {
        thisCycle = thisEntity.lSysFacComp.CycleStep;

        if (thisEntity.lSysFacComp.CycleStep >= thisEntity.lSysFacComp.MaxCycle)
        {
            thisEntity.lSysComp.NeedsDrawing = false;
            thisEntity.lSysFacComp.IsDrawing = false;
            return;
        }



        thisInstruction = InstantiateInstructionInList(thisEntity, thisEntity.lSysFacComp.InstructionList, thisCycle);


        RandomiseThisInstruction(thisInstruction);

        Debug.Log("thisCycle : " + thisCycle);
        Debug.Log("This String : " + thisEntity.lSysComp.DNA[thisEntity.lSysComp.DNA.Count - 1].ToString());

        //Debug.Log ("DNA Length : " + thisEntity.lSysComp.DNA.Length);
        switchString = thisEntity.lSysComp.DNA[thisEntity.lSysComp.DNA.Count - 1][thisCycle].ToString();

        switch (switchString)
        {
        case ">":
            thisInstruction.Angle += thisInstruction.AngleChange;
            break;

        case "<":
            thisInstruction.Angle -= thisInstruction.AngleChange;
            break;

        case "F":

            Vector2 debugpos = (AngleHelper.Vector2FromAngle(thisInstruction.Angle).normalized *thisInstruction.Length);
            //Debug.Log ("vector change: " + debugpos);
            thisInstruction.position += debugpos;
            break;

        case "+":
            thisInstruction.AngleChange += 5f;
            break;

        case "-":
            thisInstruction.AngleChange -= 5f;
            break;

        case "[":
            thisEntity.lSysFacComp.InstructionStack.Push(Instantiate(thisInstruction));
            break;

        case "]":
            thisEntity.lSysFacComp.InstructionList[thisCycle] = thisEntity.lSysFacComp.InstructionStack.Pop();
            break;

        case "O":
            thisInstruction.Size *= 1.2f;
            break;

        case "o":
            thisInstruction.Size *= 0.8f;
            break;



        case "A":

            if (thisEntity.lSysFacComp.FactoryPrefabs_A != null)
            {
                thisSpawn = (GameObject)Instantiate(thisEntity.lSysFacComp.FactoryPrefabs_A, new Vector3(thisInstruction.position.x, thisInstruction.position.y), Quaternion.identity, thisEntity.trans);
                thisEntity.lSysFacComp.Children.Add(thisSpawn);

                PaintGameObject(thisSpawn, thisInstruction);
            }

            break;

        case "B":

            if (thisEntity.lSysFacComp.FactoryPrefabs_B != null)
            {
                thisSpawn = (GameObject)Instantiate(thisEntity.lSysFacComp.FactoryPrefabs_B, new Vector3(thisInstruction.position.x, thisInstruction.position.y), Quaternion.identity, thisEntity.trans);
                thisEntity.lSysFacComp.Children.Add(thisSpawn);

                PaintGameObject(thisSpawn, thisInstruction);
            }
            break;

        case "C":

            if (thisEntity.lSysFacComp.FactoryPrefabs_A != null)
            {
                thisSpawn = (GameObject)Instantiate(thisEntity.lSysFacComp.FactoryPrefabs_A, new Vector3(thisInstruction.position.x, thisInstruction.position.y), Quaternion.identity, thisEntity.trans);
                thisEntity.lSysFacComp.Children.Add(thisSpawn);

                PaintGameObject(thisSpawn, thisInstruction);
            }
            break;



            break;
        }


        thisEntity.lSysFacComp.CycleStep += 1;
    }