// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2021 Torsten Schache, 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 Glade;
using Hiperscan.Extensions.ApoIdent.Widgets;
using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.Spectroscopy.Method;
using Hiperscan.Unix;


namespace Hiperscan.Extensions.ApoIdent
{

    public partial class ApoIdentApplication
    {
        [Widget] Gtk.Image animation_state_image = null;
        [Widget] Gtk.Image animation_info_image = null;
        [Widget] Gtk.Label animation_state_label = null;
        [Widget] Gtk.Alignment animation_menuline_alignment = null;

        [Widget] Gtk.EventBox animation_frame_eventbox = null;

        private void __UpdateAnimationSection(ApoIdentApplicationState state)
        {
            this.__UpdateAnimationSection(state, null);
        }



        private void __UpdateAnimationSection(ApoIdentApplicationState state,
                                              string message)
        {
            switch(state)
            {
                case ApoIdentApplicationState.ProgramStart:
                case ApoIdentApplicationState.ConnectionStart:
                case ApoIdentApplicationState.Exit:
                    this.Animation.Update(Widgets.AnimationState.Working);
                    this.Animation.ResetError();
                    break;

                case ApoIdentApplicationState.ConnectionStartIdentServerFailed:
                case ApoIdentApplicationState.ConnectionIdentServerRefused:
                case ApoIdentApplicationState.ConnectionIdentServerVersionRefused:
                case ApoIdentApplicationState.ConnectionCheckIdentModuleFailed:
                case ApoIdentApplicationState.ConnnectionDeviceRegistrationFailed:
                case ApoIdentApplicationState.ConnectionLoadDataFailed:
                    this.Animation.Update(Widgets.AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.ConnectionIdentModuleFailed, message);
                    break;

                case ApoIdentApplicationState.ConnectionInitDeviceFailed:
                case ApoIdentApplicationState.ConnectionInitFinderFailed:
                case ApoIdentApplicationState.CoonectDeviceWarmupFailed:
                    this.Animation.Update(Widgets.AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.ConnectionDeviceFailed, message);
                    break;

                case ApoIdentApplicationState.ConnectionWarmupEnd:
                    this.Animation.Update(Widgets.AnimationState.ReadyForSubstanceInput);
                    break;

                case ApoIdentApplicationState.ConnectionLost:
                    this.Animation.Update(Widgets.AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.ConnectionLost, message);
                    break;

                case ApoIdentApplicationState.SubstanceManagementSubstanceNoSubstanceSelected:
                    if (this.Control.ConnectionSuccess == true)
                    {
                        this.Animation.Update(AnimationState.ReadyForSubstanceInput);
                        this.Animation.ResetError();
                    }
                    break;


                case ApoIdentApplicationState.MeasuringFailedPostProcessing:
                    switch (this.Finder.MeasuringState)
                    {
                        case MeasuringState.NotMeasurable:
                            this.Animation.Update(AnimationState.NotMeasurable);
                            break;

                        case MeasuringState.Transflectance:
                            this.Animation.Update(AnimationState.ReadyForTransflectance);
                            break;

                        case MeasuringState.TransflectanceAu:
                            this.Animation.Update(AnimationState.ReadyForTransflectanceAu);
                            break;

                        case MeasuringState.MeasuringSolid:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolid);
                            break;

                        case MeasuringState.MeasuringInsert:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolidInsert);
                            break;

                        case MeasuringState.MeasuringFluid:
                            this.Animation.Update(AnimationState.ReadyForMeasurementFluid);
                            break;

                        default:
                            break;
                    }
                    break;

                case ApoIdentApplicationState.SubstanceManagementSubstanceAfterSelectionChanged:
                case ApoIdentApplicationState.MeasuringInterruptedEnd:
                    switch(this.Finder.MeasuringState)
                    {
                        case MeasuringState.NotMeasurable:
                            this.Animation.Update(AnimationState.NotMeasurable);
                            break;

                        case MeasuringState.Transflectance:
                            this.Animation.Update(AnimationState.ReadyForTransflectance);
                            break;

                        case MeasuringState.TransflectanceAu:
                            this.Animation.Update(AnimationState.ReadyForTransflectanceAu);
                            break;

                        case MeasuringState.MeasuringSolid:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolid);
                            break;

                        case MeasuringState.MeasuringInsert:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolidInsert);
                            break;

                        default:
                            break;
                    }
                    this.Animation.ResetError();
                    break;

                case ApoIdentApplicationState.MeasuringStateChanged:
                    switch(this.Finder.MeasuringState)
                    {
                        case MeasuringState.MeasuringInsert:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolidInsert);
                            break;

                        case MeasuringState.MeasuringSolid:
                            this.Animation.Update(AnimationState.ReadyForMeasurementSolid);
                            break;

                        default:
                            break;
                    }
                    break;

                case ApoIdentApplicationState.MeasuringWaitForNextCycle:
                    switch (this.Finder.MeasuringState)
                    {
                        case MeasuringState.WhiteReference:
                            this.Animation.Update(AnimationState.ReadyForWhiteReference);
                            break;

                        case MeasuringState.WhiteInsetReference:
                            this.Animation.Update(AnimationState.ReadyForWhiteInsertReference);
                            break;

                        case MeasuringState.BlackReference:
                            this.Animation.Update(AnimationState.ReadyForBlackReference);
                            break;

                        default:
                            break;
                    }
                    break;
                   
                case ApoIdentApplicationState.MeasuringRunCycle:
                    switch (this.Finder.MeasuringState)
                    {
                        case MeasuringState.WhiteReference:
                            this.Animation.Update(AnimationState.MeasuringWhiteReference);
                            break;

                        case MeasuringState.WhiteInsetReference:
                            this.Animation.Update(AnimationState.MeasuringWhiteInsertReference);
                            break;

                        case MeasuringState.BlackReference:
                            this.Animation.Update(AnimationState.MeasuringBlackReference);
                            break;
                        default:
                            break;
                    }
                    break;

                case ApoIdentApplicationState.MeasuringStart:
                    switch (this.Finder.MeasuringState)
                    {
                        case MeasuringState.Transflectance:
                            this.Animation.Update(AnimationState.MeasuringTransflectance);
                            break;

                        case MeasuringState.TransflectanceAu:
                            this.Animation.Update(AnimationState.MeasuringTransflectanceAu);
                            break;

                        case MeasuringState.MeasuringSolid:
                            this.Animation.Update(AnimationState.MeasuringSolid);
                            break;

                        case MeasuringState.MeasuringInsert:
                            this.Animation.Update(AnimationState.MeasuringSolidInsert);
                            break;

                        case MeasuringState.MeasuringFluid:
                            this.Animation.Update(AnimationState.MeasuringFluid);
                            break;

                        default:
                            break;
                    }
                    this.Animation.ResetError();
                    break;


                case ApoIdentApplicationState.MeasuringFailed:
                    this.Animation.Update(AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.MeasuringFailed, message);
                    break;

                case ApoIdentApplicationState.MeasuringTransflectanceFailed:
                    this.Animation.Update(AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.TransflectanceFailed, message);
                    break;

                case ApoIdentApplicationState.MeasuringBlackFailed:
                    this.Animation.Update(AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.BlackFailed, message);
                    break;

                case ApoIdentApplicationState.MeasuringWhiteFailed:
                    this.Animation.Update(AnimationState.Failure);
                    this.Animation.UpdateError(AnimationErrorState.WhiteFailed, message);
                    break;

                case ApoIdentApplicationState.MeasuringStartInternalCaibration:
                    this.Animation.Update(AnimationState.InternalRecalibration);
                    break;

                case ApoIdentApplicationState.MeasuringResultCheck:
                case ApoIdentApplicationState.MeasuringResultCheckRepeated:
                    if (this.SubstanceManagement.CurrentModelClass.SubstanceType == SubstanceType.Fluid)
                        this.Animation.UpdateError(AnimationErrorState.IdentificationFluidFailed, message);
                    else
                        this.Animation.UpdateError(AnimationErrorState.IdentificationSolidFailed, message);
                    break;

                case ApoIdentApplicationState.MeasuringForFirstFluid:
                    switch (this.Finder.MeasuringState)
                    {
                        case MeasuringState.MeasuringFluid:
                            this.Animation.Update(AnimationState.ReadyForMeasurementFluid);
                            break;

                        default:
                            break;
                    }
                    break;

                case ApoIdentApplicationState.MeasuringSuccess:
                case ApoIdentApplicationState.ProtocolDataChanged:
                case ApoIdentApplicationState.ResultAdditionalTestsWindowClosed:
                case ApoIdentApplicationState.ProtocolBatchDeadLineChanged:
                    if (this.Control.ProtocolState.HasFlag(ProtocolStates.IdentificationResultExists))
                    {
                        if (this.Control.ProtocolState.HasFlag(ProtocolStates.ProtocolSectionActive))
                            this.Animation.Update(AnimationState.ReadyForProtocolCreation);
                        else
                            this.Animation.Update(AnimationState.ReadyForProtocolInput);
                    }  
                    break;


                case ApoIdentApplicationState.ProtocolSavingFailed:
                    this.Animation.Update(AnimationState.SavingFailed);
                    this.Animation.UpdateError(AnimationErrorState.SaveFailed, message);
                    break;


                case ApoIdentApplicationState.ProtocolShowingFailed:
                    this.Animation.UpdateError(AnimationErrorState.PdfShowingFailed, message);
                    break;

                case ApoIdentApplicationState.ProtocolPrintingFailed:
                    this.Animation.UpdateError(AnimationErrorState.PrintingFailed, message);
                    break;

                case ApoIdentApplicationState.ProtocolLabelPrintingFailed:
                    this.Animation.UpdateError(AnimationErrorState.LabelPrintingFailed, message);
                    break;

                case ApoIdentApplicationState.ProtocolSavingSuccess:
                    this.Animation.Update(AnimationState.Saved);
                    this.Animation.ResetError(true);
                    break;

                default:
                    break;
            }
        }

        public Animation Animation { get; private  set; }
    }
}
