using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace Azyobuzi.Twirunrun
{
    public class Settings : SettingsBase<Settings>
    {
        //
        //URI短縮
        //
        private string _bitlyId;
        public string bitlyId
        {
            set
            {
                if (_bitlyId != value)
                {
                    _bitlyId = value;
                    OnPropertyChanged("bitlyId");
                }
            }
            get
            {
                return _bitlyId;
            }
        }

        private string _bitlyApiKey;
        public string bitlyApiKey
        {
            set
            {
                if (_bitlyApiKey != value)
                {
                    _bitlyApiKey = value;
                    OnPropertyChanged("bitlyApiKey");
                }
            }
            get
            {
                return _bitlyApiKey;
            }
        }

        private string selectedShortenService = ShortenUriService.bitly.Name;
        public string SelectedShortenService
        {
            set
            {
                if (!selectedShortenService.Equals(value, StringComparison.CurrentCultureIgnoreCase))
                {
                    selectedShortenService = value;
                    OnPropertyChanged("SelectedShortenService");
                }
            }
            get
            {
                return selectedShortenService;
            }
        }

        private bool autoShorten = false;
        public bool AutoShorten
        {
            set
            {
                if (autoShorten != value)
                {
                    autoShorten = value;
                    OnPropertyChanged("AutoShorten");
                }
            }
            get
            {
                return autoShorten;
            }
        }


        //
        //ビューア設定
        //
        private FormSettings viewerForm = new FormSettings()
        #region ViewerForm初期設定
        {
            Bounds = new Rectangle(100, 100, 400, 400),
            WindowState = FormWindowState.Normal
        };
        #endregion
        public FormSettings ViewerForm
        {
            set
            {
                if (!viewerForm.Equals(value))
                {
                    viewerForm = value;
                    OnPropertyChanged("ViewerForm");
                }
            }
            get
            {
                return viewerForm;
            }
        }

        private bool pictureViewerAutoSize = true;
        public bool PictureViewerAutoSize
        {
            set
            {
                if (pictureViewerAutoSize != value)
                {
                    pictureViewerAutoSize = value;
                    OnPropertyChanged("PictureViewerAutoSize");
                }
            }
            get
            {
                return pictureViewerAutoSize;
            }
        }


        //
        //表示設定
        //
        private int iconSize = 16;
        public int IconSize
        {
            set
            {
                if (iconSize != value)
                {
                    iconSize = value;
                    OnPropertyChanged("IconSize");
                }
            }
            get
            {
                return iconSize;
            }
        }

        private string mainFontString = new Font("MS UI Gothic", 9f).ConvertToString();
        public string MainFontString
        {
            set
            {
                if (mainFontString != value)
                {
                    mainFontString = value;
                    mainFont = value.ConvertToFont();
                    OnPropertyChanged("MainFontString");
                    OnPropertyChanged("MainFont");
                }
            }
            get
            {
                return mainFontString;
            }
        }

        private Font mainFont = new Font("MS UI Gothic", 9f);
        [XmlIgnore]
        public Font MainFont
        {
            set
            {
                if (!mainFont.Equals(value))
                {
                    mainFont = value;
                    mainFontString = value.ConvertToString();
                    OnPropertyChanged("MainFontString");
                    OnPropertyChanged("MainFont");
                }
            }
            get
            {
                return mainFont;
            }
        }

        private string mainFontColorString = SystemColors.ControlText.ConvertToString();
        public string MainFontColorString
        {
            set
            {
                if (mainFontColorString != value)
                {
                    mainFontColorString = value;
                    mainFontColor = value.ConvertToColor();
                    OnPropertyChanged("MainFontColorString");
                    OnPropertyChanged("MainFontColor");
                }
            }
            get
            {
                return mainFontColorString;
            }
        }

        private Color mainFontColor = SystemColors.ControlText;
        [XmlIgnore]
        public Color MainFontColor
        {
            set
            {
                if (mainFontColor != value)
                {
                    mainFontColor = value;
                    mainFontColorString = value.ConvertToString();
                    OnPropertyChanged("MainFontColorString");
                    OnPropertyChanged("MainFontColor");
                }
            }
            get
            {
                return mainFontColor;
            }
        }

        private string mainBgColorString = SystemColors.Window.ConvertToString();
        public string MainBgColorString
        {
            set
            {
                if (mainBgColorString != value)
                {
                    mainBgColorString = value;
                    mainBgColor = value.ConvertToColor();
                    OnPropertyChanged("MainBgColorString");
                    OnPropertyChanged("MainBgColor");
                }
            }
            get
            {
                return mainBgColorString;
            }
        }

        private Color mainBgColor = SystemColors.Window;
        [XmlIgnore]
        public Color MainBgColor
        {
            set
            {
                if (mainBgColor != value)
                {
                    mainBgColor = value;
                    mainBgColorString = value.ConvertToString();
                    OnPropertyChanged("MainBgColorString");
                    OnPropertyChanged("MainBgColor");
                }
            }
            get
            {
                return mainBgColor;
            }
        }

        private string retweetedBgColorString = SystemColors.Window.ConvertToString();
        public string RetweetedBgColorString
        {
            set
            {
                if (retweetedBgColorString != value)
                {
                    retweetedBgColorString = value;
                    retweetedBgColor = value.ConvertToColor();
                    OnPropertyChanged("RetweetedBgColorString");
                    OnPropertyChanged("RetweetedBgColor");
                }
            }
            get
            {
                return retweetedBgColorString;
            }
        }

        private Color retweetedBgColor = SystemColors.Window;
        [XmlIgnore]
        public Color RetweetedBgColor
        {
            set
            {
                if (retweetedBgColor != value)
                {
                    retweetedBgColor = value;
                    retweetedBgColorString = value.ConvertToString();
                    OnPropertyChanged("RetweetedBgColorString");
                    OnPropertyChanged("RetweetedBgColor");
                }
            }
            get
            {
                return retweetedBgColor;
            }
        }

        private string retweetedFontColorString = Color.Green.ConvertToString();
        public string RetweetedFontColorString
        {
            set
            {
                if (retweetedFontColorString != value)
                {
                    retweetedFontColorString = value;
                    retweetedFontColor = value.ConvertToColor();
                    OnPropertyChanged("RetweetedFontColorString");
                    OnPropertyChanged("RetweetedFontColor");
                }
            }
            get
            {
                return retweetedFontColorString;
            }
        }

        private Color retweetedFontColor = Color.Green;
        [XmlIgnore]
        public Color RetweetedFontColor
        {
            set
            {
                if (retweetedFontColor != value)
                {
                    retweetedFontColor = value;
                    retweetedFontColorString = value.ConvertToString();
                    OnPropertyChanged("RetweetedFontColorString");
                    OnPropertyChanged("RetweetedFontColor");
                }
            }
            get
            {
                return retweetedFontColor;
            }
        }

        private string postPanelFontString = new Font("MS UI Gothic", 9f).ConvertToString();
        public string PostPanelFontString
        {
            set
            {
                if (postPanelFontString != value)
                {
                    postPanelFontString = value;
                    postPanelFont = value.ConvertToFont();
                    OnPropertyChanged("PostPanelFontString");
                    OnPropertyChanged("PostPanelFont");
                }
            }
            get
            {
                return postPanelFontString;
            }
        }

        private Font postPanelFont = new Font("MS UI Gothic", 9f);
        [XmlIgnore]
        public Font PostPanelFont
        {
            set
            {
                if (!postPanelFont.Equals(value))
                {
                    postPanelFont = value;
                    postPanelFontString = value.ConvertToString();
                    OnPropertyChanged("PostPanelFontString");
                    OnPropertyChanged("PostPanelFont");
                }
            }
            get
            {
                return postPanelFont;
            }
        }

        private int nameWidth = 100;
        public int NameWidth
        {
            set
            {
                if (nameWidth != value)
                {
                    nameWidth = value;
                    OnPropertyChanged("NameWidth");
                }
            }
            get
            {
                return nameWidth;
            }
        }

        private NameTypes nameType = NameTypes.Name;
        public NameTypes NameType
        {
            set
            {
                if (nameType != value)
                {
                    nameType = value;
                    OnPropertyChanged("NameType");
                }
            }
            get
            {
                return nameType;
            }
        }


        //
        //フッタ
        //
        private string footer;
        public string Footer
        {
            set
            {
                if (footer != value)
                {
                    footer = value;
                    OnPropertyChanged("Footer");
                }
            }
            get
            {
                return footer;
            }
        }


        //
        //投稿キー
        //
        private PostKeys postKey = PostKeys.Enter;
        public PostKeys PostKey
        {
            set
            {
                if (postKey != value) { 
                    postKey = value;
                    OnPropertyChanged("PostKey");
                }
            }
            get
            {
                return postKey;
            }
        }


        //
        //並べ替え順
        //
        private SortOrder orderType = SortOrder.Descending;
        public SortOrder OrderType
        {
            set
            {
                if (orderType != value)
                {
                    orderType = value;
                    OnPropertyChanged("OrderType");
                }
            }
            get
            {
                return orderType;
            }
        }


        //
        //投稿欄の位置
        //
        private DockStyle postPanelPosition = DockStyle.Top;
        public DockStyle PostPanelPosition
        {
            set
            {
                if (postPanelPosition != value)
                {
                    postPanelPosition = value;
                    OnPropertyChanged("PostPanelPosition");
                }
            }
            get
            {
                return postPanelPosition;
            }
        }


        //
        //タブの位置
        //
        private TabAlignment tabAlignment = TabAlignment.Top;
        public TabAlignment TabAlignment
        {
            set
            {
                if (tabAlignment != value)
                {
                    tabAlignment = value;
                    OnPropertyChanged("TabAlignment");
                }
            }
            get
            {
                return tabAlignment;
            }
        }


        //
        //投稿欄の高さ
        //
        private int postPanelHeight = 75;
        public int PostPanelHeight
        {
            set
            {
                if (postPanelHeight != value)
                {
                    postPanelHeight = value;
                    OnPropertyChanged("PostPanelHeight");
                }
            }
            get
            {
                return postPanelHeight;
            }
        }


        //
        //詳細表示の高さ
        //
        private int statusBrowserHeight = 70;
        public int StatusBrowserHeight
        {
            set
            {
                if (statusBrowserHeight != value)
                {
                    statusBrowserHeight = value;
                    OnPropertyChanged("StatusBrowserHeight");
                }
            }
            get
            {
                return statusBrowserHeight;
            }
        }


        //
        //タブ
        //
        private List<TabInfo> tabs = new List<TabInfo>();
        public List<TabInfo> Tabs
        {
            set
            {
                if (!tabs.SequenceEqual(value))
                {
                    tabs = value;
                    OnPropertyChanged("Tabs");
                }
            }
            get
            {
                return tabs;
            }
        }

        //
        //新着通知
        //
        private int notifyFormShowTime = 7;
        public int NotifyFormShowTime
        {
            set
            {
                if (notifyFormShowTime != value)
                {
                    notifyFormShowTime = value;
                    OnPropertyChanged("NotifyFormShowTime");
                }
            }
            get
            {
                return notifyFormShowTime;
            }
        }

        private NotifyTypes notifyType = NotifyTypes.Balloon;
        public NotifyTypes NotifyType
        {
            set
            {
                if (notifyType != value)
                {
                    notifyType = value;
                    OnPropertyChanged("NotifyType");
                }
            }
            get
            {
                return notifyType;
            }
        }

        private int notifyCount = 4;
        public int NotifyCount
        {
            set
            {
                if (notifyCount != value)
                {
                    notifyCount = value;
                    OnPropertyChanged("NotifyCount");
                }
            }
            get
            {
                return notifyCount;
            }
        }


        //
        //UserStream
        //
        private bool streamingEnable = true;
        public bool StreamingEnable
        {
            set
            {
                if (streamingEnable != value)
                {
                    streamingEnable = value;
                    OnPropertyChanged("StreamingEnable");
                }
            }
            get
            {
                return streamingEnable;
            }
        }

        private bool streamingNotifyNewTweet = true;
        public bool StreamingNotifyNewTweet
        {
            set
            {
                if (streamingNotifyNewTweet != value)
                {
                    streamingNotifyNewTweet = value;
                    OnPropertyChanged("StreamingNotifyNewTweet");
                }
            }
            get
            {
                return streamingNotifyNewTweet;
            }
        }

        private bool autoRestart;
        public bool AutoRestart
        {
            set
            {
                if (autoRestart != value)
                {
                    autoRestart = value;
                    OnPropertyChanged("AutoRestart");
                }
            }
            get
            {
                return autoRestart;
            }
        }


        //
        //MainFormの設定
        //
        private FormSettings mainFormSetting = new FormSettings()
        #region MainForm初期設定
        {
            Bounds = new Rectangle(200, 200, 450, 500),
            WindowState = FormWindowState.Normal
        };
        #endregion
        public FormSettings MainFormSetting
        {
            set
            {
                if (!mainFormSetting.Equals(value))
                {
                    mainFormSetting = value;
                    OnPropertyChanged("MainFormSetting");
                }
            }
            get
            {
                return mainFormSetting;
            }
        }


        //
        //@・#補完
        //
        private string[] atHashtagList = new string[] { };
        public string[] AtHashtagList
        {
            set
            {
                if (!atHashtagList.SequenceEqual(value))
                {
                    atHashtagList = value;
                    OnPropertyChanged("AtHashtagList");
                }
            }
            get
            {
                return atHashtagList;
            }
        }

        private bool autoComplete = true;
        public bool AutoComplete
        {
            set
            {
                if (autoComplete != value)
                {
                    autoComplete = value;
                    OnPropertyChanged("AutoComplete");
                }
            }
            get
            {
                return autoComplete;
            }
        }
    }

    public class FormSettings : IEquatable<FormSettings>
    {
        public Rectangle Bounds { set; get; }
        public FormWindowState WindowState { set; get; }

        public static FormSettings FromForm(Form f)
        {
            return new FormSettings()
            {
                Bounds = f.Bounds,
                WindowState = f.WindowState
            };
        }

        public void Restore(Form f)
        {
            f.Bounds = Bounds;
            f.WindowState = WindowState;
        }

        public bool Equals(FormSettings other)
        {
            return this.Bounds == other.Bounds && this.WindowState == other.WindowState;
        }
    }

    public enum PostKeys
    {
        Enter,
        CtrlEnter
    }

    public enum NameTypes
    {
        Name,
        ScreenName
    }

    public enum NotifyTypes
    {
        NotifyForm,
        Balloon
    }
}
