
// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2024. Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.


using System;
using System.IO;
using System.Threading.Tasks;

using Hiperscan.Unix;
using Hiperscan.GuiExtensions;
using Hiperscan.GuiExtensions.Dialog;
using Hiperscan.Extensions.ReferenceCheck.Control.Enums;
using Hiperscan.Extensions.ReferenceCheck.Control.GuiUpdate;

namespace Hiperscan.Extensions.ReferenceCheck.Control
{
    public partial class CoreApp
    {
        private void GotoProtocolSection()
        {
            this.CurrentVisibleView = ViewTypes.Protocol;
        }

        public void SetOperatorName(string operator_name)
        {
            if (this.SessionManager.IsRestored)
                return;

            if (this.SessionManager.Operator == operator_name)
                return;

            this.SessionManager.Operator = operator_name;

            UpdateArgs args = new UpdateArgs();
            args.ViewType = ViewTypes.Protocol;
            args.UpdateCatecory = UpdateCategory.Sensitives | UpdateCategory.QuickDataChange;
            this.UpdateGuiNeeded?.Invoke(args);
        }

        public void CreateProtocol()
        {
            Task.Run(() => this.DoCreateProtocol());
        }

        private void DoCreateProtocol()
        {
            this.CurrentProgrammState = ProgramState.CreateProtocol;
            UpdateArgs args = new UpdateArgs();
            args.CursorState = CursorState.Busy;
            args.ViewType = ViewTypes.Protocol;
            args.UpdateCatecory = UpdateCategory.Sensitives;

            this.UpdateGuiNeeded?.Invoke(args);

            try
            {
                this.SessionManager.Result.Creator = this.SessionManager.Operator;
                if (this.SessionManager.Result.EvaluationSuccess == false)
                {
                    this.SessionManager.Result.Evaluate(this.SessionManager.AllSesstions,
                                                        this.SessionManager.CalibrationSessions);
                }
                this.Protocol = new Protocol.ReferenceCheckProtocol(this.SessionManager.Result,
                                                                    this.OutputDir);

                this.ProtocolCreationSuccess = true;
                this.CurrentProgrammState = ProgramState.Waiting;
              

                args = new UpdateArgs();
                args.CursorState = CursorState.Normal;
                args.ViewType = ViewTypes.Protocol;
                args.UpdateCatecory = UpdateCategory.Sensitives;

                this.UpdateGuiNeeded?.Invoke(args);

            }
            catch(Exception ex)
            {
                this.ProtocolCreationSuccess = false;
                this.CurrentProgrammState = ProgramState.Waiting;

                args = new UpdateArgs();
                args.CursorState = GuiExtensions.CursorState.Normal;
                args.ViewType = Enums.ViewTypes.Protocol;

                args.DialogArgs.StandardDialogType = StandardDialogType.Error;
                args.DialogArgs.Exception = ex;
                args.DialogArgs.Message = string.Format(Catalog.GetString("Cannot create protocol: {0}"), ex.Message);
                this.UpdateGuiNeeded?.Invoke(args);
            }
        }

        public void ShowProtocol()
        {
            try
            {
                this.Protocol.Show(this.OutputDir);
            }
            catch(Exception ex)
            {
                UpdateArgs args = new UpdateArgs();
                args.CursorState = GuiExtensions.CursorState.Normal;
                args.ViewType = Enums.ViewTypes.Protocol;

                args.DialogArgs.StandardDialogType = StandardDialogType.Error;
                args.DialogArgs.Exception = ex;
                args.DialogArgs.Message = string.Format(Catalog.GetString("Cannot show protocol: {0}"), ex.Message);
                this.UpdateGuiNeeded?.Invoke(args);
            }
        }

        public void SaveProtocol()
        {
            Task.Run(() => this.DoSaveProtocol());
        }

        private void DoSaveProtocol()
        {
            string zip_file = Path.Combine(this.LastSelectedDir, Path.GetFileName(this.OutputDir) + ".zip");
            UpdateArgs args = new UpdateArgs();
            args.DialogArgs.ZipDialogType = ZipDialogType.Save;
            args.DialogArgs.FileName = zip_file;
            this.UpdateGuiNeeded?.Invoke(args);

            if (args.DialogArgs.Response != DialogRespnseType.Ok)
                return;

            zip_file = args.DialogArgs.FileName;

            this.CurrentProgrammState = ProgramState.SaveProtocol;
            args = new UpdateArgs();
            args.CursorState = CursorState.Busy;
            args.ViewType = ViewTypes.Protocol;
            args.UpdateCatecory = UpdateCategory.Sensitives;

            this.UpdateGuiNeeded?.Invoke(args);

            try
            {
                this.ProtocolSaveSuccess = false;
                this.CurrentProgrammState = ProgramState.SaveProtocol;
                this.Save(zip_file);

                this.ProtocolSaveSuccess = true;
                this.CurrentProgrammState = ProgramState.Waiting;

                args = new UpdateArgs();
                args.CursorState = CursorState.Normal;
                args.ViewType = ViewTypes.Protocol;
                args.UpdateCatecory = UpdateCategory.Sensitives;
                this.UpdateGuiNeeded?.Invoke(args);
            }
            catch (Exception ex)
            {
                args = new UpdateArgs();
                args.CursorState = GuiExtensions.CursorState.Normal;
                args.ViewType = Enums.ViewTypes.Protocol;

                args.DialogArgs.StandardDialogType = StandardDialogType.Error;
                args.DialogArgs.Exception = ex;
                args.DialogArgs.Message = string.Format(Catalog.GetString("Cannot save protocol: {0}"), ex.Message);
                this.UpdateGuiNeeded?.Invoke(args);
                this.CurrentProgrammState = ProgramState.Waiting;
            }
        }

        public void LeaveApplication()
        {
        }

        public string ProtocolDate
        {
            get
            {
                return this.SessionManager?.CreationDate ?? String.Empty;
            }
        }

        public string ProtocolOperatorName
        {
            get
            {
                return this.SessionManager.Operator;
            }
        }

        public bool IsProtocolOperatorValid
        {
            get
            {
                return this.SessionManager.HasValidOperatorName;
            }
        }

        public bool ProtocolIsBusy
        {
            get
            {
                return this.CurrentProgrammState == ProgramState.CreateProtocol ||
                           this.CurrentProgrammState == ProgramState.SaveProtocol;
            }
        }

        public bool CanEnterOperator
        {
            get
            {
                return this.SessionManager.IsRestored == false;
            }
        }

        public bool CanCreateProtocol
        {
            get
            {
                if (this.ProtocolIsBusy)
                    return false;

                return this.IsProtocolOperatorValid && this.SessionManager.AreChangesNotSaved;
            }
        }

        public bool CanShowProtocol
        {
            get
            {
                if (this.ProtocolIsBusy || this.IsProtocolOperatorValid == false)
                    return false;

                return this.ProtocolCreationSuccess;
            }
        }

        public bool CanSaveProtocol
        {
            get
            {
                if (this.ProtocolIsBusy || this.IsProtocolOperatorValid == false)
                    return false;

                return this.ProtocolCreationSuccess;
            }
        }

        public bool CanLeaveApplication
        {
            get
            {
                if (this.ProtocolIsBusy || this.IsProtocolOperatorValid == false)
                    return false;

                return this.ProtocolSaveSuccess;
            }
        }

        private bool ProtocolCreationSuccess { get; set; } = false;
        private bool ProtocolSaveSuccess { get; set; } = false;
    }
}
