// Created with MonoDevelop
//
//    Copyright (C) 2023 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.Collections.Generic;
using System.Threading;

using Hiperscan.Unix;
using Hiperscan.SGS.Common;
using Hiperscan.SGS.Benchtop;
using Hiperscan.SGS.SgsNt.Protocol;
using Hiperscan.SGS.SerialInterface;

namespace Hiperscan.SGS.SgsNt
{
    internal partial class DeviceNt1_6 : DeviceNt1_5
    {
        public DeviceNt1_6(DeviceInfo info, VersionInfo version) : base(info, version)
        {
        }

        public override void SetFinderPosition(int position, IdleTaskHandler idle_task, bool no_wait = false)
        {
            if (this.IsFinder == false)
                return;

            BaseProtocol.Command command = new BaseProtocol.Command(new BaseProtocol.Command(Protocol.PeripheralSetFinderPosition))
            {
                Int32Value = DeviceNt1_6.Positions[this.Info.DeviceType][position]
            };

            this.FinderPosition = MotorPositions.Moving;
            lock (this)
                this.state_changed = true;

            int timeout_ms = (position == MotorPositions.Initial) ? 20000 : 10000;
            BaseProtocol.Response response = this.WriteCommand(command, timeout_ms, idle_task);

            if (response == null)
                throw new SgsException(Catalog.GetString("Cannot set motor position."), this);

            this.FinderPosition = position;

            if (no_wait) return;

            this.SetState(Spectrometer.State.Waiting);
            idle_task?.Invoke();
            Thread.Sleep(200);
            this.SetState(Spectrometer.State.Idle);
        }

        protected static readonly Dictionary<DeviceType, Dictionary<int, int>> Positions = new Dictionary<DeviceType, Dictionary<int, int>>()
        {
            {
                DeviceType.ApoIdent,
                new Dictionary<int, int>()
                {
                    { FinderWheelPosition.Initial, 0 },
                    { FinderWheelPosition.White, -25600 },
                    { FinderWheelPosition.Reference, 25600 },
                    { FinderWheelPosition.Sample, -51200 },
                    { FinderWheelPosition.Reserved1, 1 },
                    { FinderWheelPosition.Standby, 1 },
                }
            },
            {
                DeviceType.FinderX ,
                new Dictionary<int, int>()
                {
                    {MotorPositions.Initial, 0},
                    {MotorPositions.ParkPosition, -3840},
                    {MotorPositions.Standby, 71168},
                    {MotorPositions.Sample1, 93952},
                    {MotorPositions.Sample2, 141312},
                    {MotorPositions.Sample3, 185600},
                    {MotorPositions.LeftSample, 90386},
                    {MotorPositions.RightSample, 177920},
                    {MotorPositions.Fix2GlassOxid, 17920},
                    {MotorPositions.Fix2GlassBlack, -3840},
                    {MotorPositions.Fix2GlassWhite, 39680},
                }
            }
        };
    }
}