﻿using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shiftobj
{
    public abstract class RenderConfig : BindableBase
    {
        /// <summary>
        /// 画像の余白
        /// </summary>
        public static readonly int Margin = 32;

        public RenderConfig()
        {
            _referenceAddonCollection = new List<Addon>();

            this.ToggleShowBackgroundImage = new DelegateCommand(() => this.IsShowBackgroundImage = !this.IsShowBackgroundImage);
            this.ToggleShowMark = new DelegateCommand(() => this.IsShowMark = !this.IsShowMark);
            this.ToggleShowGround = new DelegateCommand(() => this.IsShowGround = !this.IsShowGround);
            this.ToggleShowTrack = new DelegateCommand(() => this.IsShowTrack = !this.IsShowTrack);
            this.ToggleShowGroundTemplate = new DelegateCommand(() => this.IsShowGroundTemplate = !this.IsShowGroundTemplate);
            this.ToggleShowConstraintTemplate = new DelegateCommand(() => this.IsShowConstraintTemplate = !this.IsShowConstraintTemplate);

            this.ZoomTo100 = new DelegateCommand(() => this.Scale = 1);
            this.ZoomOut = new DelegateCommand(() => this.Scale -= 1);
            this.ZoomIn = new DelegateCommand(() => this.Scale += 1);

            this.ToggleShowGrid = new DelegateCommand(() => this.IsShowGrid = !this.IsShowGrid);
            this.ZoomOutGrid = new DelegateCommand(() => { this.IsShowGrid = true; this.GridSize /= 2; });
            this.ZoomInGrid = new DelegateCommand(() => { this.IsShowGrid = true; this.GridSize *= 2; });
        }

        private int _gridSize = 8;
        private int _scale = 1;

        private bool _isShowBackgroundImage = false;
        private bool _isShowMark = true;
        private bool _isShowGround = true;
        private bool _isShowTrack = false;
        private bool _isShowGroundTemplate = false;
        private bool _isShowConstraintTemplate = false;
        private bool _isShowGrid = false;
        private bool _isShowReference = false;
        private bool _isShowConstraintReference = false;
        private bool _isShowConstraint = false;

        private Addon _referenceAddon;
        private List<Addon> _referenceAddonCollection;

        public void RegisterReferenceAddonCollection(AddonCollection document)
        {
            _referenceAddonCollection.AddRange(document.Addons);
        }

        public void ClearReferenceAddonCollection()
        {
            _referenceAddonCollection.Clear();
            ReferenceAddon = null;
        }

        public Addon LookupAddon(string name)
        {
            if (!string.IsNullOrEmpty(name))
                name = name.ToLower();
            
            switch (name)
            {
                case null:
                case "":
                case "none":
                    return null;
                default:
                    Addon addon = _referenceAddonCollection.FirstOrDefault(e => e.Name.ToLower() == name);
                    if (addon == null)
                        System.Diagnostics.Debug.WriteLine($"(LookupAddon) missing addon : {name}");
                    return addon;
            }
        }


        /// <summary>
        /// 線路の画像
        /// </summary>
        public abstract Dictionary<WayType, Bitmap>  TrackImages{ get; }
        
        /// <summary>
        /// ひし形テンプレートの画像
        /// </summary>
        public abstract Dictionary<WayType, Bitmap> GroundTemplateImages { get; }

        /// <summary>
        /// 前後の連結車両用の画像
        /// </summary>
        public abstract Bitmap ConstraintTemplateImage { get; }

        public bool IsShowBackgroundImage
        {
            get
            {
                return this._isShowBackgroundImage;
            }

            set
            {
                this.SetProperty(ref this._isShowBackgroundImage, value);
            }
        }

        public bool IsShowMark
        {
            get
            {
                return this._isShowMark;
            }

            set
            {
                this.SetProperty(ref this._isShowMark, value);
            }
        }

        public bool IsShowGround
        {
            get
            {
                return this._isShowGround;
            }

            set
            {
                this.SetProperty(ref this._isShowGround, value);
            }
        }

        public bool IsShowTrack
        {
            get
            {
                return this._isShowTrack;
            }

            set
            {
                this.SetProperty(ref this._isShowTrack, value);
            }
        }

        public bool IsShowGroundTemplate
        {
            get
            {
                return this._isShowGroundTemplate;
            }

            set
            {
                this.SetProperty(ref this._isShowGroundTemplate, value);
            }
        }

        public bool IsShowConstraintTemplate
        {
            get
            {
                return this._isShowConstraintTemplate;
            }

            set
            {
                this.SetProperty(ref this._isShowConstraintTemplate, value);
            }
        }

        public bool IsShowConstraint
        {
            get
            {
                return this._isShowConstraint;
            }

            set
            {
                this.SetProperty(ref this._isShowConstraint, value);
            }
        }

        public bool IsShowGrid
        {
            get
            {
                return this._isShowGrid;
            }

            set
            {
                this.SetProperty(ref this._isShowGrid, value);
            }
        }

        public bool IsShowReference
        {
            get
            {
                return this._isShowReference;
            }

            set
            {
                this.SetProperty(ref this._isShowReference, value);
            }
        }

        public bool IsShowConstraintReference
        {
            get
            {
                return this._isShowConstraintReference;
            }

            set
            {
                this.SetProperty(ref this._isShowConstraintReference, value);
            }
        }


        /// <summary>
        /// ズーム倍率
        /// </summary>
        public int Scale
        {
            get
            {
                return this._scale;
            }

            set
            {
                if ((value != this._scale) && (1 <= value) && (value <= 8))
                {
                    this.SetProperty(ref this._scale, value);
                }
            }
        }

        /// <summary>
        /// 市松グリッドのサイズ
        /// </summary>
        public int GridSize
        {
            get
            {
                return this._gridSize;
            }

            set
            {
                if (value > 0)
                {
                    this.SetProperty(ref this._gridSize, value);
                }
            }
        }

        /// <summary>
        /// 参考用アドオン
        /// </summary>
        public Addon ReferenceAddon
        {
            get
            {
                return this._referenceAddon;
            }
            set
            {
                this.SetProperty(ref this._referenceAddon, value);
            }
        }

        /// <summary>
        /// Pakset側のタイルサイズ
        /// </summary>
        public abstract int GameTileSize { get; }

        public DelegateCommand ToggleShowBackgroundImage { get; private set; }
        public DelegateCommand ToggleShowMark { get; private set; }
        public DelegateCommand ToggleShowGround { get; private set; }
        public DelegateCommand ToggleShowTrack { get; private set; }
        public DelegateCommand ToggleShowGroundTemplate { get; private set; }
        public DelegateCommand ToggleShowConstraintTemplate { get; private set; }

        public DelegateCommand ZoomTo100 { get; private set; }
        public DelegateCommand ZoomOut { get; private set; }
        public DelegateCommand ZoomIn { get; private set; }

        public DelegateCommand ToggleShowGrid { get; private set; }
        public DelegateCommand ZoomOutGrid { get; private set; }
        public DelegateCommand ZoomInGrid { get; private set; }
    }

    public class RenderConfig64 : RenderConfig
    {
        private static Dictionary<WayType, Bitmap> _trackImages = new Dictionary<WayType, Bitmap>()
        {
            {WayType.Track, new Bitmap(@"pack://application:,,,/Resources/track.png") },
            {WayType.Tram, new Bitmap(@"pack://application:,,,/Resources/way-tram.png") },
            {WayType.Air, new Bitmap(@"pack://application:,,,/Resources/way-air.png") },
            {WayType.Water, new Bitmap(@"pack://application:,,,/Resources/way-water.png") },
            {WayType.Road, new Bitmap(@"pack://application:,,,/Resources/way-road.png") },
        };

        private static Bitmap _defaultGroundTemplateImage = new Bitmap(@"pack://application:,,,/Resources/vhcl.png");

        private static Dictionary<WayType, Bitmap> _groundTemplateImages = new Dictionary<WayType, Bitmap>()
        {
            {WayType.Track, _defaultGroundTemplateImage },
            {WayType.Tram, _defaultGroundTemplateImage },
            {WayType.Air, _defaultGroundTemplateImage },
            {WayType.Water, _defaultGroundTemplateImage },
            {WayType.Road, new Bitmap(@"pack://application:,,,/Resources/vhcl-road.png") },
        };

        private Bitmap _constraintTemplateBitmap = new Bitmap(@"pack://application:,,,/Resources/box.png");

        public override int GameTileSize => 64;
        /// <summary>
        /// 線路の画像
        /// </summary>
        public override Dictionary<WayType, Bitmap> TrackImages => _trackImages;

        /// <summary>
        /// ひし形テンプレートの画像
        /// </summary>
        public override Dictionary<WayType, Bitmap> GroundTemplateImages => _groundTemplateImages;

        /// <summary>
        /// 前後の連結車両用の画像
        /// </summary>
        public override Bitmap ConstraintTemplateImage => this._constraintTemplateBitmap;
    }
}
