//*************************************************************
//  Filename:       Generic.cs
//  Author:         MaesterRowen & Wondro (TeamFSD)
//  Date:           August 10, 2013
//  Description:    Misc enums/classes/structs for program management.
//*************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace XuiWorkshop
{
    public enum ERROR
    {
        S_OK,
        S_ERROR
    }

    public enum FORMSTATE
    {
        XUI_READ,
        XUR_READ,
        RECURSIVE,
        XUI_INFO,
        NONE
    }

    public struct PROCESS_FLAGS
    {
        public bool useXam;
        public bool xuiToolVersion;
        public bool useAnimations;
        public bool extFile;
    }

    public static class XuiTypeConvert
    {
        public static XUICOLOR ToXuiColor(this string s)
        {
            XUICOLOR color = new XUICOLOR();
            color.argb = Convert.ToUInt32(s, 16);
            return color;
        }
        public static XUIQUATERNION ToXuiQuaternion(this string s)
        {
            XUIQUATERNION quan = new XUIQUATERNION();

            string[] split = s.Split(',');
            quan.x = Single.Parse(split[0]);
            quan.y = Single.Parse(split[1]);
            quan.z = Single.Parse(split[2]);
            quan.w = Single.Parse(split[3]);
            return quan;
        }
        public static XUIVECTOR ToXuiVector(this string s)
        {
            XUIVECTOR vec = new XUIVECTOR();

            string[] split = s.Split(',');
            vec.x = Single.Parse(split[0]);
            vec.y = Single.Parse(split[1]);
            vec.z = Single.Parse(split[2]);
            return vec;
        }
        public static XUICUSTOM ToXuiCustom(this string s)
        {
            XUICUSTOM cust = new XUICUSTOM();
            XUIBEZIERPOINT points = new XUIBEZIERPOINT();
            XUIPOINT point = new XUIPOINT();

            string[] split = s.Split(',');
            cust.NumPoints = Convert.ToUInt32(split[0]);

            int rootCount = 1;
            for (int i = 0; i < Convert.ToInt32(split[0]); i++)
            {
                point.x = Single.Parse(split[rootCount]);
                rootCount++;
                point.y = Single.Parse(split[rootCount]);
                rootCount++;

                points.vecPoint = point;

                point.x = Single.Parse(split[rootCount]);
                rootCount++;
                point.y = Single.Parse(split[rootCount]);
                rootCount++;

                points.vecCtrl1 = point;

                point.x = Single.Parse(split[rootCount]);
                rootCount++;
                point.y = Single.Parse(split[rootCount]);
                rootCount+=2;

                points.vecCtrl2 = point;

                cust.Points.Add(points);
            }

            point.x = cust.Points.Max(x => x.vecPoint.x);
            point.y = cust.Points.Max(y => y.vecPoint.y);

            cust.BoundingBox = point;

            cust.DataLen = 8 + 4 + cust.NumPoints * 24;

            return cust;
        }

        public static object FormatPropType(string value, XUIELEM_PROP_TYPE propType)
        {
            switch (propType)
            {
                case XUIELEM_PROP_TYPE.XUI_EPT_BOOL:
                    return Convert.ToBoolean(value);
                case XUIELEM_PROP_TYPE.XUI_EPT_COLOR:
                    return value.ToXuiColor();
                case XUIELEM_PROP_TYPE.XUI_EPT_CUSTOM:
                    return value.ToXuiCustom();
                case XUIELEM_PROP_TYPE.XUI_EPT_FLOAT:
                    return float.Parse(value);
                case XUIELEM_PROP_TYPE.XUI_EPT_INTEGER:
                    return Convert.ToInt32(value);
                case XUIELEM_PROP_TYPE.XUI_EPT_QUATERNION:
                    return value.ToXuiQuaternion();
                case XUIELEM_PROP_TYPE.XUI_EPT_STRING:
                    return value;
                case XUIELEM_PROP_TYPE.XUI_EPT_UNSIGNED:
                    return Convert.ToUInt32(value);
                case XUIELEM_PROP_TYPE.XUI_EPT_VECTOR:
                    return value.ToXuiVector();
            }
            return null;
        }
    }

    public static class Global
    {
        public static string[] ignoreClasses = { "XuiVisual", "XuiText", "XuiImage", "XuiTextPresenter", "XuiImagePresenter", "XuiNineGrid", "XuiFigure" };
        public static bool writeExtFile { get; set; }

        public static void RemoveDesignTimeElements(XUIOBJECTDATA obj)
        {
            List<XUIOBJECTDATA> designTime = obj.ChildrenArray.FindAll(x => x.GetPropVal("DesignTime").ToString() == "True");

            foreach (XUIOBJECTDATA child in designTime)
            {
                obj.ChildrenArray.Remove(child);
            }

            foreach (XUIOBJECTDATA child in obj.ChildrenArray)
            {
                RemoveDesignTimeElements(child);
            }
        }

        public static void ReorderProperties(XUIOBJECTDATA obj)
        {
            obj.PropertyArray.Sort((x, y) => x.PropDef.Id.CompareTo(y.PropDef.Id));

            foreach (XUIOBJECTDATA child in obj.ChildrenArray)
                ReorderProperties(child);
        }

        public static void BuildHeriarchyId(XUIOBJECTDATA obj)
        {
            obj.HeriarchyId = obj.GetPropVal("Id").ToString();

            if (obj.HeriarchyId == "" || obj.HeriarchyId == "XuiCanvas0")
                obj.HeriarchyId = obj.ClassName;

            foreach(XUIOBJECTDATA child in obj.ChildrenArray)
                BuildHeriarchyId(child, obj);
        }

        public static void BuildHeriarchyId(XUIOBJECTDATA obj, XUIOBJECTDATA parent)
        {
            obj.HeriarchyId = parent.HeriarchyId + "#" + obj.GetPropVal("Id").ToString();

            foreach(XUIOBJECTDATA child in obj.ChildrenArray)
                BuildHeriarchyId(child, obj);
        }

        [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

        // Associate file extension with progID, description, icon and application
        public static void AssociateXUR()
        {
            Registry.ClassesRoot.CreateSubKey(".xur").SetValue("", "XUR8.Document");

            using (RegistryKey key = Registry.ClassesRoot.CreateSubKey("XUR8.Document"))
            {
                key.SetValue("", "XUR File");
                key.CreateSubKey("DefaultIcon").SetValue("", "\"" + Application.ExecutablePath + "\",2");

                // Delete the key instead of trying to change it
                //string keyPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + extension;
                //RegistryKey CurrentUser = Registry.CurrentUser.OpenSubKey(keyPath, true);
                //CurrentUser.DeleteSubKey("UserChoice", false);
                //CurrentUser.Close();

                // Tell explorer the file association has been changed
                SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
            }
        }

        // Return true if extension already associated in registry
        public static bool IsAssociated()
        {
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(".xur");
            object value = key.GetValue("", "XUR8.Document");

            return value.ToString() == "XUR8.Document";
        }
    }
}
