// 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 System;
using Hiperscan.Unix;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class ApoIdentApplication
    {
        private void InitScanner()
        {
            this.Scanner = new Scanner();
            this.Scanner.ScanDetected += this.OnScanDetected;
            this.ScanRecognizer = new ScanRecognizer(this.MainWindow, this.Config.ScannerSettings);
            this.ScanRecognizer.TextScanDetected += OnTextScanDetected;
        }

        private void OnTextScanDetected(object sender, EventArgs e)
        {
            if (this.Control.ScanState.HasFlag(ScanStates.AllowScan))
            {
                string scan = (sender as ScanRecognizer).ScannedValue;
                bool capslock_active = (sender as ScanRecognizer).CapsLockActive;
                Console.WriteLine("Emit scan: {0} (CapsLock = {1})", scan, capslock_active);
                this.Scanner.EmitScan(scan, capslock_active);
            }
        }

        private void OnScanDetected(object sender, EventArgs e)
        {
            if (this.Finder == null || this.Finder.IsApoIdent1)
                return;

            lock (this.Control.Transaction)
            {
                string messagge = String.Empty;

                if (this.Scanner.ScannerInfo.CapsLockActive)
                {
                    messagge = Catalog.GetString("Scan is invalid because the CAPSLOCK key is active.");

                    this.Update(ApoIdentApplicationState.ShowErrorDialogWithoutSerivceDialog, messagge);

                    if (this.SubstanceManagement.ProtocolCompletion == ProtocolAutoCompletionType.Scanner)
                        this.Scanner.ScannerInfo = this.Scanner.PreviewScanInfo;

                    this.Scanner.CycleIsRunning = false;
                    return;
                }

                if (this.Scanner.ScannerInfo.IsValid == false)
                {
                    if (String.IsNullOrEmpty(this.Scanner.ScannerInfo.Ppn?.Trim()) == false)
                        messagge = String.Format(Catalog.GetString("Cannot find the PPN {0} in the Apo-Ident substance database."), this.Scanner.ScannerInfo.Ppn.Trim());
                    else
                        messagge = Catalog.GetString("The scan is not valid or incomplete. Please close this window and retry.");

                    this.Update(ApoIdentApplicationState.ShowErrorDialogWithoutSerivceDialog, messagge);

                    if (this.SubstanceManagement.ProtocolCompletion == ProtocolAutoCompletionType.Scanner)
                        this.Scanner.ScannerInfo = this.Scanner.PreviewScanInfo;

                    this.Scanner.CycleIsRunning = false;
                    return;
                }

                if (this.SubstanceManagement.ContainsEntryForScan(this.Scanner.ScannerInfo) == false)
                {
                    messagge += this.Scanner.ScannerInfo.SubstanceId;

                    if (String.IsNullOrEmpty(this.Scanner.ScannerInfo.RegisteredName))
                        messagge = Catalog.GetString("No substance name");
                    else
                        messagge = this.Scanner.ScannerInfo.RegisteredName;

                    messagge = String.Format(Catalog.GetString("Cannot find scanned substance '{0}' in our substance database."),
                                             messagge);
                    this.Update(ApoIdentApplicationState.ShowErrorDialogWithoutSerivceDialog, messagge);

                    if (this.SubstanceManagement.ProtocolCompletion == ProtocolAutoCompletionType.Scanner)
                        this.Scanner.ScannerInfo = this.Scanner.PreviewScanInfo;

                    this.Scanner.CycleIsRunning = false;
                    return;
                }

                this.Scanner.PreviewScanInfo = this.Scanner.ScannerInfo;
                this.SubstanceManagement.SelectNewSubstance(this.Scanner.ScannerInfo);
                this.Scanner.CycleIsRunning = false;
            }
        }

        private void OnMainWindowScanFocusedIn(object sender, EventArgs args)
        {
            this.Control.IsTopLevelWindow = true;

            if (this.Control.IsGuiUpdating == true)
                return;

            this.Update(ApoIdentApplicationState.MainWindowFocus);
        }

        private void OnMainWindowScanFocusedOut(object sender, EventArgs args)
        {
            this.Control.IsTopLevelWindow = false;

            if (this.Control.IsGuiUpdating == true)
                return;

            this.Update(ApoIdentApplicationState.MainWindowFocus);
        }

        private void OnScanStateChanged(ScanStates state)
        {
            if (state == ScanStates.AllowScan)
                this.Scanner?.StartPolling();
            else
                this.Scanner?.StopPolling();
        }

        private void OnMeasurementProgressStateChanged(MeasuringProgressStates state)
        {
            if (this.Control.MeasuringProgressState.IsProcessing)
                this.Control.ScanState.DeleteFlag(ScanStates.IsNotMeasuring);
            else
                this.Control.ScanState.SetFlag(ScanStates.IsNotMeasuring);
        }

        private Scanner Scanner { get; set; }
        private ScanRecognizer ScanRecognizer { get; set; }
    }
}