using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
using RpcScannerClient.Events;
using Valg.EVA.Skanning.Scan.ReadSoftEmulation.Events.Rpc;

namespace Valg.EVA.Skanning.Scan.ReadSoftEmulation.ScannerAccess
{
    internal class IsisAgent : ScannerAgent, IDisposable
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        [DllImport("user32.dll")]
        private static extern IntPtr GetActiveWindow();
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        private readonly string _configFilename;
        private readonly ScannerConfig _scannerConfig;
        private RpcClient _rpcClient;

        private readonly AutoResetEvent _scanningDoneEvent = new AutoResetEvent(false);

        public IsisAgent(ScannerConfig scannerConfig)
        {
            _scannerConfig = scannerConfig;
            _configFilename = scannerConfig.ConfigFilename;
        }

        public override void StartScanning()
        {
            Aborted = false;
            if (_rpcClient == null)
            {

               _rpcClient = GetRpcClient();
                
            }

                _rpcClient.Scan();
           
            _scanningDoneEvent.WaitOne();
        }

        public override void AbortScanning()
        {
            Aborted = true;
        }

        internal RpcClient GetRpcClient()
        {
            var ret = new RpcClient();

            ret.FeederEmpty +=  RpcClient_FeederEmpty;
            ret.DocumentScanned += RpcClient_DocumentScanned;
            ret.Error += RpcClient_ScanningError;
            ret.InitializeScanner(((ScannerModel)_scannerConfig.ScannerDefinition).ModelName, _configFilename);
            
            return ret;
        }

        private void RpcClient_FeederEmpty(object sender, RpcFeederEmptyEventArgs e)
        {
            OnFeederEmpty();
            _scanningDoneEvent.Set();
        }

        private void RpcClient_DocumentScanned(object sender, RpcDocumentScannedEventArgs e)
        {
            OnDocumentScanned(e.Document.FrontImage.ToByteArray(), e.Document.BackImage.ToByteArray(), true);
            if (Aborted)
            {
                _scanningDoneEvent.Set();
                _rpcClient.StopScanning();
            }
        }

        private void RpcClient_ScanningError(object sender, RpcScanningErrorEventArgs e)
        {
            OnScanningError(new Exception(e.ErrorText));
            _scanningDoneEvent.Set();
        }





        public void Dispose()
        {
            _rpcClient?.ReleaseScanner();

        }
    }
}

