using Unity.IO.Compression;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

public static class StringExtensions {

    public static int ToInt(this string str){
        return int.Parse(str);
    }
    public static Color ToColor(this string str){
        var color = default(Color);
        if(ColorUtility.TryParseHtmlString(str, out color)){
            return color;
        }else{
#if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
            Debug.LogError(string.Format("無効な色指定 {0} があるので修正して下さい。フォーマットは #000000 です。", str));
#endif
            return Color.magenta;
        }
    }
    public static int ToLayer(this string str){
        return LayerMask.NameToLayer(str);
    }
    public static int ToLayerMask(this string str){
        return 1 << ToLayer(str);
    }
    public static int ToLayerMask(params string[] strArray){
        int result = 0;
        foreach(var str in strArray){
            result |= ToLayerMask(str);
        }
        return result;
    }
    public static List<int> ToIntList(this string str){
        if(str == null){
            return new List<int>();
        }else{
            return str.Split(',').Select(Int32.Parse).ToList();
        }
    }

    static public bool CheckPictograph(this string text){
        Encoding sjisEncode = Encoding.GetEncoding("Shift_JIS");
        return text != sjisEncode.GetString(sjisEncode.GetBytes(text));
    }

    static public int CompareVersion(this string a, string b){
        if(a == b) return 0;
        string[] splitA = a.Split('.');
        string[] splitB = b.Split('.');
        int max = Math.Max(splitA.Length, splitB.Length);
        for(int i = 0; i < max; ++i){
            if(i >= splitA.Length) return 1;
            if(i >= splitB.Length) return -1;
            int result = Int32.Parse(splitA[i]) - Int32.Parse(splitB[i]);
            if(result != 0) return result; // 1に正規化すべきかどうか
        }
        return 0;
    }

    public static bool IsVersion(this string str){
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"[0-9]+\.[0-9]+\.[0-9]+");
        return regex.IsMatch(str);
    }

    public static string Compression(this string str){
        byte[] source = Encoding.UTF8.GetBytes(str);
        byte[] resultBytes;
        using(MemoryStream ms = new MemoryStream()){
            DeflateStream CompressedStream = new DeflateStream(ms, CompressionMode.Compress, true);
            CompressedStream.Write(source, 0, source.Length);
            CompressedStream.Close();
            resultBytes = ms.ToArray();
        }
        return Convert.ToBase64String(resultBytes, Base64FormattingOptions.InsertLineBreaks);
    }

    public static string DeCompression(this string str){
        byte[] source = Convert.FromBase64String(str);
        byte[] resultBytes;
        using(MemoryStream ms = new MemoryStream(source))
        using(MemoryStream ms2 = new MemoryStream()){
            DeflateStream CompressedStream = new DeflateStream(ms, CompressionMode.Decompress);
            while(true){
                int rb = CompressedStream.ReadByte();
                if(rb == -1) break;
                ms2.WriteByte((byte)rb);
            } 
            resultBytes = ms2.ToArray();
        }
        return Encoding.UTF8.GetString(resultBytes);
    }

    public static string DataToXML<T>(T data, bool isShorten = true){
        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        using(MemoryStream memoryStream = new MemoryStream()){
            serializer.WriteObject(memoryStream, data);
            return Encoding.UTF8.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
        }
    }

    public static T XMLToData<T>(string xml) where T : class {
        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        using(MemoryStream memoryStream = new MemoryStream()){
            byte[] data = Encoding.UTF8.GetBytes(xml);
            memoryStream.Write(data, 0, data.Length);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return serializer.ReadObject(memoryStream) as T;
        }
    }
}
