public void BeginEndTurn()
    {
        if(m_pathPlanner.Path.Count > 1)
        {
            if(m_pathPlanner.DistanceAlongPath < m_pathPlanner.Path.Count - 1)
            {
                m_pathPlanner.DistanceAlongPath++;

                m_targetPos = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath].transform.position;
                m_targetTile = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath];
            }
            else
            {
                m_pathPlanner.Path.Clear();
            }
        }
    }
    public void BeginEndTurn()
    {
        if(m_pathPlanner.Path.Count > 1)
        {
            m_onSecondTileMove = false;
            if(m_pathPlanner.DistanceAlongPath < m_pathPlanner.Path.Count - 1)
            {
                m_pathPlanner.DistanceAlongPath++;

                m_targetPos = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath].transform.position;
                m_movementTargetTile = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath];
            }
            else
            {
                if(Tile.Army != TargetArmy)
                {
                    PlanPath();
                }
            }
        }
    }
    // Update is called once per frame
    void Update()
    {
        if(m_pathPlanner.Path.Count == 0)
        {
            PlanPath();
        }

        if(transform.position != m_targetPos)
        {
            Vector3 delta = m_targetPos - transform.position;
            float deltaDist = delta.magnitude;

            if(deltaDist > Speed)
            {
                delta.Normalize();
                delta *= Speed;
            }
            else // Change tile
            {
                Tile = m_movementTargetTile;
                if(Tile.Army == TargetArmy)
                {
                    TargetArmy.SetObjective(TargetArmyNewObjective);
                    Faction.m_orders.Remove(this);
                    Destroy(this.gameObject);
                }
                if(m_onSecondTileMove == false)
                {
                    m_onSecondTileMove = true;

                    if(m_pathPlanner.DistanceAlongPath < m_pathPlanner.Path.Count - 1)
                    {
                        m_pathPlanner.DistanceAlongPath++;

                        m_targetPos = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath].transform.position;
                        m_movementTargetTile = m_pathPlanner.Path[m_pathPlanner.DistanceAlongPath];
                    }
                    else
                    {
                        if(Tile.Army != TargetArmy)
                        {
                            PlanPath();
                        }
                    }
                }
            }

            transform.position += delta;
            var tempPos = transform.position;
            transform.position = tempPos;//Need to do this properly sometime
        }
    }
    public void PlanPath(WorldTileScript start, WorldTileScript destination, bool ignorePassability)
    {
        bool[,] closed = new bool[worldGrid.TileCountX, worldGrid.TileCountY];
        WorldTileScript[,] parent = new WorldTileScript[worldGrid.TileCountX, worldGrid.TileCountY];

        List<WorldTileScript> openList = new List<WorldTileScript>();
        List<int> costList = new List<int>();
        List<int> distFromDest = new List<int>();

        openList.Add(destination);
        distFromDest.Add(0);
        costList.Add(CalcDistance(start, destination));

        while(openList.Count > 0)
        {
            int currentIndex = GetNearest(openList, costList);
            WorldTileScript current = openList[currentIndex];
            int currentCostToTile = costList[currentIndex];
            closed[current.x, current.y] = true;
            openList.RemoveAt(currentIndex);
            distFromDest.RemoveAt(currentIndex);
            costList.RemoveAt(currentIndex);

            if(current == start)
            {
                UnHighlightPath();

                // found so copy the path:
                m_path.Clear();
                DistanceAlongPath = 0;
                WorldTileScript pathHead = start;
                while(true)
                {
                    m_path.Add(pathHead);
                    pathHead = parent[pathHead.x, pathHead.y];
                    if(pathHead == destination)
                    {
                        m_path.Add(pathHead);
                        break;
                    }
                }
                break;
            }

            foreach(WorldTileScript neighbour in current.GetNeighbours())
            {
                if(!neighbour.IsPassable && !ignorePassability)
                {
                    closed[neighbour.x, neighbour.y] = true;
                }

                if(closed[neighbour.x, neighbour.y])
                {
                    continue;
                }

                int costToHere = currentCostToTile + 1;
                int dist = CalcDistance(start, neighbour);

                int openListIndex = openList.FindIndex( a => a == neighbour);

                if(openListIndex == -1)
                {
                    openList.Add(neighbour);
                    costList.Add(costToHere);
                    distFromDest.Add(dist);
                    parent[neighbour.x, neighbour.y] = current;
                }
                else
                {
                    if(costToHere < costList[openListIndex])
                    {
                        distFromDest[openListIndex] = dist;
                        costList[openListIndex] = costToHere;
                        parent[neighbour.x, neighbour.y] = current;
                    }
                }
            }
        }
    }
    int CalcDistance(WorldTileScript start, WorldTileScript end)
    {
        Vector3 startVec = start.GetComponent<Transform>().position;
        Vector3 endVec = end.GetComponent<Transform>().position;

        return (int)Vector3.Distance(startVec, endVec);
    }
    void OnMouseDown()
    {
        if(!m_selected && Faction == m_worldGrid.PlayerFaction)
        {
            m_positionWhenPickedUp = transform.position;
            m_selected = true;
            m_latched = true;

            if(!m_tile)
            {
                Vector3 newPos = m_positionWhenPickedUp;
                newPos.y = HoverPlane;
                RaycastHit tileHit;
                bool hit = Physics.Raycast(newPos, new Vector3(0.0f, -1.0f, 0.0f), out tileHit, 2.0f * HoverPlane);

                if(hit)
                {
                    WorldTileScript tile = tileHit.collider.gameObject.GetComponent<WorldTileScript>();
                    if(tile)
                    {
                        m_tile = tile;
                    }
                }
            }
        }
    }
 public void SetObjective(WorldTileScript objectiveTile)
 {
     m_pathPlanner.PlanPath(m_tile, objectiveTile, false);
 }
    // Update is called once per frame
    void Update()
    {
        if(m_selected)
        {
            Vector3 newPos = m_worldGrid.hoverTile.transform.position;
            newPos.y += HoverPlane;
            transform.position = newPos;

            if(Input.GetMouseButtonUp(0))
            {
                m_latched = false;
            }

            if(Input.GetMouseButtonDown(0) && !m_latched)
            {
                m_selected = false;
                transform.position = m_positionWhenPickedUp;

                if(Faction.HomeArmy == this)
                {
                    if(m_tile &&
                       m_worldGrid.hoverTile.IsPassable)
                    {
                        SetObjective(m_worldGrid.hoverTile);
                    }
                }
                else
                {
                    Transform ordersOrigin = Faction.HomeArmy.transform;
                    Transform orders = (Transform)Instantiate(OrdersPrefab, ordersOrigin.position, ordersOrigin.rotation);
                    OrdersCourierScript os = orders.gameObject.GetComponent<OrdersCourierScript>();
                    os.TargetArmy = this;
                    os.TargetArmyNewObjective = m_worldGrid.hoverTile;
                    os.Faction = Faction;
                    os.Tile = Faction.HomeArmy.Tile;
                    Faction.m_orders.Add(os);
                }
            }
        }
        else
        {
            if(transform.position != m_targetPos)
            {
                Vector3 delta = m_targetPos - transform.position;
                float deltaDist = delta.magnitude;

                if(deltaDist > Speed)
                {
                    delta.Normalize();
                    delta *= Speed;
                }
                else
                {
                    if(m_tile)
                    {
                        m_tile.ArmyExit(this);
                    }
                    m_tile = m_targetTile;
                    m_tile.ArmyEnter(this);
                }

                transform.position += delta;
            }
        }
    }
    // Use this for initialization
    void Start()
    {
        m_worldGrid = GameObject.Find("WorldGrid").GetComponent<WorldGridScript>();
        m_pathPlanner = this.GetComponent<WorldPathPlanner>();

        m_xBound = m_worldGrid.XBounds;
        m_yBound = m_worldGrid.YBounds;

        m_targetPos = transform.position;

        this.gameObject.GetComponent<Renderer>().material.color = Faction.FactionColor;

        RaycastHit tileHit;
        bool hit = Physics.Raycast(transform.position, new Vector3(0.0f, -1.0f, 0.0f), out tileHit, 2.0f * HoverPlane);

        if(hit)
        {
            WorldTileScript tile = tileHit.collider.gameObject.GetComponent<WorldTileScript>();
            if(tile)
            {
                m_tile = tile;
                m_tile.ArmyEnter(this);
            }
        }
        Territory = new List<WorldTileScript>();
    }
    public void SetNeighbours(WorldTileScript[] neighbours)
    {
        m_neighbours = new WorldTileScript[neighbours.Length];

        for(int i = 0; i < neighbours.Length; i++)
        {
            m_neighbours[i] = neighbours[i];
        }
    }