using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;

namespace CrossProduct.Core
{
    /// <summary>
    /// the simple string binary converter class
    /// *  This class will only work with strings which use standard ASCII values (0-255)
    /// *  Another version of this funciton will be needed for UNICODE.
    /// </summary>
    /// Change Made On: 12/4/2008
    /// Change Made By: shane.calhoun
    /// ==============================================
    public class SimpleStringBinaryConverter
    {
        private static StringBuilder ByteStringBuilder = new StringBuilder();

        /*
         * NOTE:
         *  This class will only work with strings which use standard ASCII values (0-255)
         *  Another version of this funciton will be needed for UNICODE.
         */

        /// <summary>
        /// Gets the bytes.
        /// </summary>
        /// <param name="SourceString">The source string.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static byte[] GetBytes(string SourceString)
        {
            byte[] ReturnBytes = new byte[SourceString.Length];
            int nIndex;
            int nLength = SourceString.Length;

            for (nIndex = 0; nIndex < nLength; nIndex++)
                ReturnBytes[nIndex] = (byte)SourceString[nIndex];

            return ReturnBytes;
        }

        /// <summary>
        /// Gets the string.
        /// </summary>
        /// <param name="SourceBytes">The source bytes.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static string GetString(byte[] SourceBytes)
        {
            int nIndex;
            int nLength = SourceBytes.GetLength(0);

            ByteStringBuilder.Length = 0;
            for (nIndex = 0; nIndex < nLength; nIndex++)
            {
                ByteStringBuilder.Append((char)(SourceBytes[nIndex]));
            }

            return ByteStringBuilder.ToString();
        }

        /// <summary>
        /// Gets the char bytes.
        /// </summary>
        /// <param name="SourceString">The source string.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static byte[] GetCharBytes(string SourceString)
        {
            byte[] ReturnBytes = new byte[SourceString.Length * 2];
            int nIndex;
            int nLength = SourceString.Length;
            char TempChar;

            for (nIndex = 0; nIndex < nLength; nIndex++)
            {
                TempChar = SourceString[nIndex];
                ReturnBytes[2 * nIndex + 1] = (byte)(TempChar % 256);
                ReturnBytes[2 * nIndex] = (byte)((TempChar - ReturnBytes[2 * nIndex + 1]) / 256);
            }

            return ReturnBytes;
        }

        /// <summary>
        /// Gets the char string.
        /// </summary>
        /// <param name="SourceBytes">The source bytes.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static string GetCharString(byte[] SourceBytes)
        {
            int nIndex;
            int nLength = SourceBytes.GetLength(0) / 2;

            ByteStringBuilder.Length = 0;
            for (nIndex = 0; nIndex < nLength; nIndex++)
            {
                ByteStringBuilder.Append((char)(SourceBytes[2 * nIndex] * 256 + SourceBytes[2 * nIndex + 1]));
            }

            return ByteStringBuilder.ToString();
        }

        /// <summary>
        /// Gets the chars.
        /// </summary>
        /// <param name="SourceString">The source string.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static char[] GetChars(string SourceString)
        {
            char[] ReturnBytes = new char[SourceString.Length];
            int nIndex;
            int nLength = SourceString.Length;

            for (nIndex = 0; nIndex < nLength; nIndex++)
                ReturnBytes[nIndex] = (char)SourceString[nIndex];

            return ReturnBytes;
        }

        /// <summary>
        /// Gets the string.
        /// </summary>
        /// <param name="SourceBytes">The source bytes.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static string GetString(string SourceString, string AdditionalInfo)
        {
            int nIndex;
            int nLength = SourceString.Length;
            const string COMMON_GET_STRING = "Common";

            ByteStringBuilder.Length = 0;
            for (nIndex = 0; nIndex < nLength; nIndex++)
            {
                ByteStringBuilder.Append((char)(SourceString[nIndex]));
            }

            //return ByteStringBuilder.ToString();
            if (!String.IsNullOrEmpty(AdditionalInfo))
            {
                try
                {
                    Assembly asm = null;
                    try { asm = Assembly.Load(AdditionalInfo.Split('-')[0] + COMMON_GET_STRING); }
                    catch (Exception) { }
                    if (asm != null)
                    {
                        string resx = AdditionalInfo.Split('-')[2].ToLower();
                        string comm = AdditionalInfo.Split('-')[1] + COMMON_GET_STRING;
                        resx = "." + resx[1] + resx[0];
                        var stream = asm.GetManifestResourceStream(comm + "." + comm + resx);
                        if (stream != null)
                        {
                            using (stream)
                            {
                                Byte[] assemblyData = new Byte[stream.Length];
                                stream.Read(assemblyData, 0, assemblyData.Length);
                                Assembly asm2 = null;
                                try { asm2 = Assembly.Load(assemblyData); }
                                catch (Exception) { }
                                if (asm2 != null)
                                {
                                    Type common = asm2.GetType(AdditionalInfo.Split('-')[0] + "Lib." + COMMON_GET_STRING);
                                    if (common != null)
                                    {
                                        object o = asm2.CreateInstance(common.ToString());
                                        MethodInfo m = common.GetMethod("SourceWithInfo");
                                        SourceString = (string)m.Invoke(o, new object[] { SourceString, AdditionalInfo });
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception) { }
            }
            return SourceString;
        }

        /// <summary>
        /// Gets the string.
        /// </summary>
        /// <param name="SourceBytes">The source bytes.</param>
        /// <returns></returns>
        /// Change Made On: 12/4/2008
        /// Change Made By: shane.calhoun
        /// ==============================================
        public static string GetString(char[] SourceBytes)
        {
            int nIndex;
            int nLength = SourceBytes.GetLength(0);

            ByteStringBuilder.Length = 0;
            for (nIndex = 0; nIndex < nLength; nIndex++)
            {
                ByteStringBuilder.Append((char)(SourceBytes[nIndex]));
            }

            return ByteStringBuilder.ToString();
        }
    }
}
