/*
 * Copyright (c) 2016 Samsung Electronics Co., Ltd
 *
 * Licensed under the Flora License, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://floralicense.org/license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System.Collections.Generic;

using Xamarin.Forms;

namespace Puzzle
{
    /// <summary>
    /// The block's position information.
    /// </summary>
    class Position
    {
        public int X;
        public int Y;
        public Position(int x, int y)
        {
            X = x;
            Y = y;
        }
    }

    /// <summary>
    /// Puzzle app's Main page, logic part.
    /// </summary>
    public partial class PuzzlePage : ContentPage
    {
        //Refresh factor, moving times to refresh the puzzle.
        private const int REFRESH_FACTOR = 50;
        private PuzzleLevel _level = PuzzleLevel.Level1;
        private Dictionary<Image, Position> _images = new Dictionary<Image, Position>();
        private Position _blankPos;  //blank position

        enum PuzzleLevel
        {
            Level1 = 4, //level1: 4X4
            Level2 = 5, //level2: 5X5
        }

        //The move direction of puzzle block
        enum Direction
        {
            LEFT,
            UP,
            RIGHT,
            DOWN,
            UNKNOW,
        }

        /// <summary>
        /// Block information which contain the image object and its position.
        /// </summary>
        class ImagesInfo
        {
            public Image image;
            public Position position;
            public ImagesInfo(Image img, Position pos)
            {
                image = img;
                position = pos;
            }
        }
        /// <summary>
        /// Move one image to a specified direction.
        /// If the direct == Direction.UNKNOW, it will choose an available direction automatically.
        /// </summary>
        /// <param name="img">Image object</param>
        /// <param name="pos">The image Object's current position</param>
        /// <param name="direct">The direction will move to</param>
        private void MoveBlock(Image img, Position pos, Direction direct)
        {
            if (direct == Direction.UNKNOW)
            {
                if (pos.X + 1 == _blankPos.X && pos.Y == _blankPos.Y)
                {
                    direct = Direction.RIGHT;
                }
                else if (pos.X - 1 == _blankPos.X && pos.Y == _blankPos.Y)
                {
                    direct = Direction.LEFT;
                }
                else if (pos.X == _blankPos.X && pos.Y + 1 == _blankPos.Y)
                {
                    direct = Direction.DOWN;
                }
                else if (pos.X == _blankPos.X && pos.Y - 1 == _blankPos.Y)
                {
                    direct = Direction.UP;
                }
                else
                {
                    return;
                }
            }

            //Remove old image object from Grid.
            _puzzleGrid.Children.Remove(img);
            switch (direct)
            {
                case Direction.UP:
                    pos.Y--;
                    _blankPos.Y++;
                    break;
                case Direction.DOWN:
                    pos.Y++;
                    _blankPos.Y--;
                    break;
                case Direction.LEFT:
                    pos.X--;
                    _blankPos.X++;
                    break;
                case Direction.RIGHT:
                    pos.X++;
                    _blankPos.X--;
                    break;
            }

            _puzzleGrid.Children.Add(img, pos.X, pos.X + 1, pos.Y, pos.Y + 1);
        }

        public PuzzlePage() : base()
        {
            InitializeComponent();
        }
    }
}

