﻿// COPYRIGHT © 2017 Sebastian Sejud
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in 
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using Urge.Editor.Dialogs;

namespace Urge.Editor.DocumentForms
{
    internal class DocumentForm: Form
    {
        private string _fileName;
        private bool _isDirty;

        protected virtual string FileFilter { get; } = "";

        protected virtual string DefaultFileName { get; } = "";

        protected virtual string EditorName { get; } = "";

        private readonly Timer _timer = new Timer
        {
            Interval = 200,
            Enabled = true
        };

        protected bool IsDirty
        {
            get
            {
                return _isDirty;
            }

            set
            {
                _isDirty = value;
                UpdateName();
            }
        }

        public DocumentForm(string path): this()
        {
            _fileName = path;
        }

        public DocumentForm()
        {
        }

        private void _timer_Tick(object sender, EventArgs e)
        {
            UpdateUi();
        }

        protected virtual void UpdateUi()
        {

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            _timer.Tick += _timer_Tick;
            _timer.Start();
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
            UpdateName();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            if (!IsDirty) return;

            switch(MessageBox.Show("Do you want to save changes?", "Unsaved changes", MessageBoxButtons.YesNoCancel))
            {
                case DialogResult.Yes:
                    Save();
                    if(IsDirty) e.Cancel = true;
                    break;

                case DialogResult.No:
                    break;

                case DialogResult.Cancel:
                    e.Cancel = true;
                    break;
            }
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            HostForm.Current.Unregister(this);
        }

        protected void Save()
        {
            if (_fileName == null)
            {
                SaveAs();
                return;
            }

            using (var stream = File.OpenWrite(_fileName))
            {
                Save(stream);
            }
        }

        private void UpdateName()
        {
            var name = _fileName == null ? Path.GetFileNameWithoutExtension(DefaultFileName) : Path.GetFileNameWithoutExtension(_fileName);
            name = $"U.R.G.E. {EditorName}: {name}" + (IsDirty ? "*" : "");
            Text = name;
        }

        protected void SaveAs()
        {
            var dialog = new SaveFileDialog
            {
                Filter = $"{FileFilter}|All Files (*.*)|*.*",
                RestoreDirectory = true,
                DefaultExt = $"*{Path.GetExtension(DefaultFileName)}",
                FileName = _fileName != null ? Path.GetFileName(_fileName) : DefaultFileName
            };

            if (dialog.ShowDialog() != DialogResult.OK) return;

            var fileName = dialog.FileName;
            using (var stream = File.OpenWrite(fileName))
            {
                Save(stream);
                _fileName = fileName;
            }
        }

        protected void Open()
        {
            var dialog = new OpenFileDialog
            {
                CheckFileExists = true,
                Filter = $"{MapDocumentForm.TheFileFilter}|All Files (*.*)|*.*",
                RestoreDirectory = true
            };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                NewEditorInstanceDialog.ProcessFile(dialog.FileName);
            }
        }

        protected virtual void Save(Stream stream)
        {

        }

        protected virtual void Redo()
        {

        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Y | Keys.Control:
                    Redo();
                    return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
}
