// ALL RIGHTS RESERVED:
// ====================
// The contents of this file, and associated files in this directory, are 
// Copyright (C) SPT , all rights reserved, 2009.
// All software Source Code, Images, Database-Design and code, Graphics Design 
// and source files, and related content (collectively referred to as SOURCE) are 
// Copyright (c) SPT, 2009, All Rights Reserved.
// http://SerialPortTool.com

// PTZ Controller is a Registered Trademark of SerialPortTool.com.

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Collections.Generic;

using PTZController;

using Spt.Share.Data;
using SPT.PTZ.Core;

namespace PTZController.Core
{
    public enum ScanMode
    {
        autoPan = 0,
        presetScan
    }

    [XmlRoot("configure")]
    public class PtzConfigure
    {
        /// <summary>
        /// Ctor
        /// </summary>
        public PtzConfigure()
        {
            if (Controller.PortNames.Length > 0)
            {
                ComPort = Controller.PortNames[0];
            }

            this.ViewType = 0;

            this.Cameras = new Logic.CameraItemList(CameraCount);
            this.Customs = new Logic.CustomItemList(CustomizePresetCount, CustomCount);
            this.States = new PanelStateList(PanelPoints, false);
            this.TourSpan = new StaySpan(DefaultTourSpan, SpanUnit.Second);
            this.TourItems = new Logic.TourItemCollection();
        }

        /// <summary>
        /// Ctor
        /// </summary>
        public PtzConfigure(Size mainFormSz)
        {
            if (Controller.PortNames.Length > 0)
            {
                ComPort = Controller.PortNames[0];
            }

            this.ViewType = 0;

            // reset default values
            foreach (Screen i in Screen.AllScreens)
            {
                if (i.Primary)
                {
                    this.m_mainFormX = i.Bounds.Left + (i.Bounds.Width - mainFormSz.Width) / 2;
                    this.m_mainFormY = i.Bounds.Top + (i.Bounds.Height - mainFormSz.Height) / 2;
                }
            }

            this.Cameras = new Logic.CameraItemList(CameraCount);
            this.Customs = new Logic.CustomItemList(CustomizePresetCount, CustomCount);
            this.States = new PanelStateList(PanelPoints, false);
            this.TourSpan = new StaySpan(DefaultTourSpan, SpanUnit.Second);
            this.TourItems = new Logic.TourItemCollection();
        }

        public static PtzConfigure Load(string path, Size mainFormSz)
        {
            PtzConfigure config = null;

            try
            {
                TextReader reader = new StreamReader(path );
                XmlSerializer serializer = new XmlSerializer(typeof(PtzConfigure));

                config = serializer.Deserialize(reader) as PtzConfigure;
                reader.Close();
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);

                config = new PtzConfigure(mainFormSz);
            }

            return config;
        }

        public void Save(string basePath, PanelForm[] panels)
        {
            TextWriter writer = new StreamWriter(basePath );
            XmlSerializer serializer = new XmlSerializer(typeof(PtzConfigure));

            m_states.Update(panels);

            serializer.Serialize(writer, this);
            writer.Close();
        }

        public override string ToString()
        {
            return string.Format("{0} {1} {2}", ComPort, BaudRate, ProtocolName);
        }

        public bool IsPanasonic()
        {
            bool flag = (ProtocolName == Controller.PanasonicV1) ||
                (ProtocolName == Controller.PanasonicV2);

            return flag;
        }

        /// <summary>
        /// Selected camera index
        /// </summary>
        private int m_cameraIndex = 0;

        public int CameraIndex
        {
            get { return m_cameraIndex; }
            set { m_cameraIndex = value; }
        }

        /// <summary>
        /// Selected preset index
        /// </summary>
        private int m_presetIndex = 0;

        public int PresetIndex
        {
            get { return m_presetIndex; }
            set { m_presetIndex = value; }
        }
       
        private UInt32 m_viewType;

        public UInt32 ViewType
        {
            get { return m_viewType; }
            set { m_viewType = value; }
        }

        /// <summary>
        /// Current protocol name
        /// </summary>
        private string m_protocolName = Controller.PelcoD;

        public string ProtocolName
        {
            get { return m_protocolName; }
            set { m_protocolName = value; }
        }

        /// <summary>
        /// Current COM port string
        /// </summary>
        private string m_comPort;

        public string ComPort
        {
            get { return m_comPort; }
            set { m_comPort = value; }
        }

        /// <summary>
        /// Current baud rate
        /// </summary>
        private int m_baudRate = 2 * Controller.BaudRateMin;

        public int BaudRate
        {
            get { return m_baudRate; }
            set { m_baudRate = value; }
        }

        /// <summary>
        /// Auto scan direction flag
        /// </summary>
        private bool m_clockWise = true;

        public bool ClockWise
        {
            get { return m_clockWise; }
            set { m_clockWise = value; }
        }

        /// <summary>
        /// Auto scan speed
        /// </summary>
        private int m_scanSpeed = Controller.MinScanSpeed;

        public int ScanSpeed
        {
            get { return m_scanSpeed; }
            set { m_scanSpeed = value; }
        }
	

        /// <summary>
        /// Main form position x coordinate
        /// </summary>
        private int m_mainFormX;
        
        public int MainFormX
        {
            get { return m_mainFormX; }
            set { m_mainFormX = value; }
        }

        /// <summary>
        /// Main form position y coordinate
        /// </summary>
        private int m_mainFormY;
        
        public int MainFormY
        {
            get { return m_mainFormY; }
            set { m_mainFormY = value; }
        }

        /// <summary>
        /// Default tour span
        /// </summary>
        private Spt.Share.Data.StaySpan _tourSpan;

        public Spt.Share.Data.StaySpan TourSpan
        {
            get { return _tourSpan; }
            set { _tourSpan = value; }
        }

        /// <summary>
        /// Cameras collection
        /// </summary>
        private Logic.CameraItemList m_cameras;

        [XmlElement("cameras")]
        public Logic.CameraItemList Cameras
        {
            get { return m_cameras; }
            set { m_cameras = value; }
        }

        /// <summary>
        /// Custom item collection
        /// </summary>
        private Logic.CustomItemList m_customs;

        [XmlElement("customs")]
        public Logic.CustomItemList Customs
        {
            get { return m_customs; }
            set { m_customs = value; }
        }
        /// <summary>
        /// Panel state collection
        /// </summary>
        private PanelStateList m_states;

        [XmlElement("states")]
        public PanelStateList States
        {
            get { return m_states; }
            set { m_states = value; }
        }

        private ScanMode _scanWay = ScanMode.presetScan;

        public ScanMode ScanWay
        {
            get { return _scanWay; }
            set { _scanWay = value; }
        }
	

        /// <summary>
        /// Default tour items
        /// </summary>
        private Logic.TourItemCollection _tourItems;

        [XmlElement("tourItems")]
        public Logic.TourItemCollection TourItems
        {
            get { return _tourItems; }
            set { _tourItems = value; }
        }



        public const int PanelCount = 2;
        public const int CameraCount = 256;
        public const int PresetCount = 127;
        public const int AuxCount = 10;
        public const int CustomCount = 12;

        public const int BroadcastAddress = 255;

        public const int CustomizePresetCount = 9;

        public const UInt32 CameraView = 0x01;
        public const UInt32 PresetView = 0x02;

        public const int DefaultTourSpan = 5;

        private const string XmlConfigName = @"config.xml";

        private static readonly Point AuxPanelPoint = new Point(216, 498);
        private static readonly Point CustomPanelPoint = new Point(223, -17);

        public static readonly Point[] PanelPoints = new Point[]
        {
            AuxPanelPoint, CustomPanelPoint
        };
    }
}
