// 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.Text;
using System.Reflection;
using System.IO;
using System.Xml;
using System.IO.Ports;
using Microsoft.Win32;
using System.Drawing;
using System.Diagnostics;
using System.Globalization;
using System.Collections;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace PTZController
{
    class HelpFunction
    {

        /// <summary>
        /// Get the help file path
        /// </summary>
        /// <returns></returns>
        public static string GetHelpPath()
        {
            string locationPath = GetCurrentPath();
            return locationPath + "\\PTZ Helper.chm";
        }

        /// <summary>
        /// Get current exe path
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentPath()
        {
            Assembly app = Assembly.GetExecutingAssembly();
            string locationPath = Path.GetDirectoryName(app.ManifestModule.FullyQualifiedName);
            return locationPath;
        }


        /// <summary>
        /// this function will get build No from assembly version
        /// </summary>
        /// <returns></returns>
        public static string GetBuildVersion()
        {
            Assembly app = Assembly.GetExecutingAssembly();
            Version v = app.GetName().Version;
            string version = string.Format("v {0}.{1}", v.Major, v.Minor);
            return version;

        }

        /// <summary>
        /// Return configure file
        /// </summary>
        /// <returns></returns>
        public static string GetConfigFile()
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            path = string.Concat(path, "\\Serial Port Tool\\PTZ Controller");
            Directory.CreateDirectory(path);    // Create directory if not exists.

            path = string.Concat(path, "\\config.xml");
            return path;
        }

        /// <summary>
        /// this function will get build No from assembly version
        /// </summary>
        /// <returns></returns>
        public static string GetRevision()
        {
            Assembly app = Assembly.GetExecutingAssembly();
            FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(app.Location);
            string version = string.Format("Build {0}", versionInfo.FilePrivatePart);
            return version;

        }

        /// <summary>
        /// return full file version like 2.0.2.22
        /// </summary>
        /// <returns></returns>
        public static string GetFullFileVersion()
        {
            Assembly app = Assembly.GetExecutingAssembly();
            FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(app.Location);
            string version = versionInfo.FileVersion;
            return version;
        }

        public static void CreateControlRegion(Control control, Region region)
        {
            if (control == null || region == null)
            {
                return;
            }

            if (control is System.Windows.Forms.Form)
            {
                try
                {
                    Form form = (Form)control;
                    form.Region = region;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                }
            }
        }

        public static void CreateControlRegion(Control control, Bitmap bitmap)
        {
            if (control == null || bitmap == null)
            {
                return;
            }

            control.Width = bitmap.Width;
            control.Height = bitmap.Height;

            if (control is System.Windows.Forms.Form)
            {
                Form form = (Form)control;
                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);

                form.Region = new Region(graphicsPath);
            }
            else if (control is System.Windows.Forms.Button)
            {
                Button button = (Button)control;

                button.Text = "";
                button.Cursor = Cursors.Hand;
                button.BackgroundImage = bitmap;

                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
                button.Region = new Region(graphicsPath);
            }
        }

        public static Region CalculateBitmapRegion(Image image)
        {
            Bitmap bmp = new Bitmap(image);
            GraphicsPath path = CalculateControlGraphicsPath(bmp);

            bmp.Dispose();

            return new Region(path);
        }

        private static unsafe GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
        {
            BitmapData data = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);

            UInt32* p = (UInt32*)data.Scan0;
            UInt32 key = *p;

            GraphicsPath path = new GraphicsPath();

            for (int y = 0; y < data.Height; y++)
            {
                UInt32* l = p;

                for (int x = 0; x < data.Width; x++)
                {
                    if (l[x] != key)
                    {
                        int n = x++; // record it

                        while (l[x] != key && x < data.Width)
                        {
                            x++;
                        }

                        path.AddRectangle(new Rectangle(n, y, x - n, 1));
                    }
                }

                p += data.Stride / sizeof(UInt32);
            }

            bitmap.UnlockBits(data);

            return path;
        }

        /// <summary>
        /// Parse a string to get the last digital value
        /// E.g. button10, you'll get 10
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static int ParseIndex(string text)
        {
            Regex ex = new Regex(@"\d{1,}");
            Match m = ex.Match(text);
            int idx = -1;

            idx = int.Parse(m.Value);

            return idx;
        }


        /// <summary>
        /// return byte array from hex string
        /// the string should be in format like
        /// ef 02 0a ..
        /// seperated by space or comma
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] GetHexFromString(string str)
        {
            ArrayList list = new ArrayList();
            string[] splitStr = HelpFunction.SplitString(str, new char[] { ' ', ',', '\r', '\n', '\t' });
            for (int i = 0; i < splitStr.Length; i++)
            {
                int dec = 0;
                try
                {
                    dec = Convert.ToInt32(splitStr[i], 16);
                }
                catch (Exception)
                {
                    throw new Exception("Wrong Format");
                }

                if (dec > 255)
                {
                    throw new Exception("Wrong Format");
                }
                list.Add((byte)dec);
            }
            return (byte[])list.ToArray(typeof(byte));

        }


        /// <summary>
        /// Split string according the dilimer, this function is equea to 
        /// String.Split(char[], StringSplitOptions.RemoveEmptyEntries)
        /// which is not supported by .net cf
        /// </summary>
        /// <param name="splitStr"></param>
        /// <returns></returns>
        private static string[] SplitString(string str, char[] separator)
        {
            string[] splitStr = str.Split(separator);
            System.Collections.ArrayList list = new System.Collections.ArrayList();
            for (int i = 0; i < splitStr.Length; i++)
            {
                if (splitStr[i] != string.Empty && splitStr[i] != null)
                {
                    list.Add(splitStr[i]);
                }
            }
            splitStr = new string[list.Count];
            list.CopyTo(splitStr);
            return splitStr;
        }

    }
}
