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

using Hiperscan.SGS.Common;


namespace Hiperscan.SGS.SerialInterface
{

    public class RemoteSerialInterfaceClient : Hiperscan.SGS.SerialInterface.ISerialInterface
    {
        private RemoteSerialInterface remote_serial_interface;
        private Guid session_id;
        
        private DeviceInfo device_info_cache;
        
        
        public RemoteSerialInterfaceClient(string server, uint port)
        {
            this.remote_serial_interface = RemoteSerialInterface.GetRemoteObject(server, port);

            this.Server     = server;
            this.Port       = port;
            this.session_id = Guid.Empty;
        }

        public void Disconnect()
        {
            this.remote_serial_interface = null;
        }
        
        public uint GetNumberOfDevices()
        {
            // remote clients are not supposed to do that
            return 0;
        }
        
        public IEnumerable<DeviceInfo> GetDeviceList()
        {
            // remote clients are not supposed to do that
            return new DeviceInfo[0];
        }
        
        public void OpenBySerialNumber(string serial)
        {
            this.session_id = this.remote_serial_interface.Open(this.Port, Environment.MachineName);
        }
        
        public void Close()
        {
            this.remote_serial_interface.Close(this.Port);
            this.session_id = Guid.Empty;
        }
        
        public void ResetDevice()
        {
            this.remote_serial_interface.ResetDevice(this.Port, this.session_id);
        }
        
        public void SetTimeouts(int read_timeout, int write_timeout)
        {
            this.remote_serial_interface.SetTimeouts(this.Port, this.session_id, read_timeout, write_timeout);
        }
        
        public void SetTimeouts()
        {
            this.remote_serial_interface.SetTimeouts(this.Port, this.session_id);
        }
        
        public void SetLatency()
        {
            this.remote_serial_interface.SetLatency(this.Port, this.session_id);
        }
        
        public void Purge()
        {
            this.remote_serial_interface.Purge(this.Port, this.session_id);
        }
        
        public uint Write(byte[] data)
        {
            return this.remote_serial_interface.Write(this.Port, this.session_id, data);
        }
        
        public uint Read(out byte[] data)
        {
            return this.remote_serial_interface.Read(this.Port, this.session_id, out data);
        }
        
        public uint Read(out byte[] data, uint len)
        {
            return this.remote_serial_interface.Read(this.Port, this.session_id, out data, len);
        }
        
        public byte[] ReadBlocking(uint len, int timeout, IdleTaskHandler idle_task)
        {
            return this.remote_serial_interface.ReadBlocking(this.Port, this.session_id, len, timeout);
        }
        
        public DriverType DriverType 
        { 
            get { return this.remote_serial_interface.GetDriverType(this.Port); }
        }
        
        public DeviceInfo DeviceInfo
        {
            get 
            {
                if (this.device_info_cache == null)
                {
                    this.device_info_cache = this.remote_serial_interface.GetDeviceInfo(this.Port);
                    this.device_info_cache.RemoteSerialInterfaceClient = this;
                }
                return this.device_info_cache;
            }
        }
        
        public VersionInfo VersionInfo
        {
            get { return this.remote_serial_interface.GetVersionInfo(this.Port); }
        }

        public string Server { get; }
        public uint   Port   { get; }
    }
}

