using UnityEngine;
using System.Collections;
using System;
using System.Xml;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

public class CheckDateUseful : MonoBehaviour {

    private bool IsQuit = false;
    private bool IsShowTips = false;
    // Use this for initialization

    private DateTime t1, t2, t11;
    string original_filepath = "";
    string encode_filepath = "";
    string decode_filepath = "";
    private int time_days = 30;//有效期30天

    // Use this for initialization
    void Start()
    {
        DontDestroyOnLoad(gameObject);
        t2 = DateTime.Now;
        t1 = DateTime.Now;

        tipStyle = new GUIStyle();
        tipStyle.fontSize = 40;
        tipStyle.normal.textColor = Color.red;

        original_filepath = Application.dataPath + @"/StreamingAssets/xml/Validity.xml";
        encode_filepath = Application.dataPath + @"/StreamingAssets/xml/enValidity.xml";
        decode_filepath = Application.dataPath + @"/StreamingAssets/xml/deValidity.xml";

        ControlXML();
    }
    string appid = "AXKC";
    bool useFul = true;
    DateTime RegistrationDate;
    DateTime LastUseTime;
    public DateTime GetRegistrationDate(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "RegistrationDate")
                {
                    return Convert.ToDateTime(elem.InnerText);
                }
            }
        }
        return DateTime.Now;
    }
    public DateTime GetLastUseTime(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "LastUseTime")
                {
                    return Convert.ToDateTime(elem.InnerText);
                }
            }
        }
        return DateTime.Now;
    }
    public void SetLastUseTime(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "LastUseTime")
                {
                    elem.InnerText = Convert.ToString(DateTime.Now);
                }
            }
            xmlDoc.Save(filepath);
        }
    }
    public bool GetUseful(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "Useful")
                {
                    return Convert.ToBoolean(elem.InnerText);
                }
            }
        }
        return false;
    }
    public void SetUsefulFalse(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "Useful")
                {
                    elem.InnerText = Convert.ToString(false);
                }
            }
            xmlDoc.Save(filepath);
        }
    }
    public void FirstSetXML(string filepath)
    {
        if (File.Exists(filepath))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNode root = xmlDoc.SelectSingleNode("assets");
            XmlNodeList nodeList = root.ChildNodes;
            foreach (XmlElement elem in nodeList)
            {
                if (elem.Name == "Useful")
                {
                    elem.InnerText = Convert.ToString(true);
                }
                if (elem.Name == "FirstExecute")
                {
                    elem.InnerText = Convert.ToString(true);
                }
                if (elem.Name == "RegistrationDate")
                {
                    elem.InnerText = Convert.ToString(DateTime.Now);
                }
                if (elem.Name == "OverTime")
                {
                    
                }
                if (elem.Name == "LastUseTime")
                {
                    elem.InnerText = Convert.ToString(DateTime.Now);
                }
            }
            xmlDoc.Save(filepath);
        }
    }
   
    private GUIStyle tipStyle;
    private int timer = 5;
    string tips = "试用期已到,";
    void OnGUI()
    {
        if (IsQuit)
        {
            t2 = DateTime.Now;
            if (t2 - t11 > new TimeSpan(0, 0, 1))
            {
                if (timer > 0)
                    timer--;
                t11 = t2;
            }
            GUI.Label(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 75, 300, 150), tips + timer + "秒后退出!", tipStyle);
           // Debug.LogError(tips);
            if (t2 - t1 > new TimeSpan(0, 0, 5))
            {
                Debug.Log("程序退出!");
                Application.Quit();
            }
        }
        if (IsShowTips)
        {
            t2 = DateTime.Now;
            if (t2 - t11 > new TimeSpan(0, 0, 1))
            {
                if (timer > 0)
                    timer--;
                t11 = t2;
            }
            //GUI.Label(new Rect(Screen.width / 2 - 150, Screen.height / 2 - 75, 300, 150), tips + timer + "秒后关闭提示!", tipStyle);
            Debug.LogWarning(tips);
            if (t2 - t1 > new TimeSpan(0, 0, 3))
            {
                IsShowTips = false;
            }

        }
    }
    // Update is called once per frame


    //xml文件加密解密

    void ControlXML()
    {
        if (File.Exists(original_filepath))//如果找到原始文件,证明这次是第一次运行该程序,配置文件数据更新并生成加密文件
        {
            FirstSetXML(original_filepath);
            GenerateEncodeXML1(original_filepath);
        }
        else
        {
            if (File.Exists(encode_filepath))
            {
                fileDcryption(encode_filepath);
                if (File.Exists(decode_filepath))
                {
                    CheckUseful();

                    GenerateEncodeXML1(decode_filepath);
                    File.Delete(decode_filepath);
                }
            }
            else
            {
                tips = "未检测到配置文件,";
                IsQuit = true;
                IsShowTips = false;
                return;
            }
        }
    }

    void CheckUseful()
    {
        useFul = GetUseful(decode_filepath);
        if (!useFul)
        {
            tips = "试用期已到,";
            IsQuit = true;
            IsShowTips = false;
            return;
        }
        LastUseTime = GetLastUseTime(decode_filepath);//上一次使用的时间
        if (DateTime.Now < LastUseTime)
        {
            tips = "检测到时间不匹配,";
            SetUsefulFalse(decode_filepath);
            IsQuit = true;
            IsShowTips = false;
            return;
        }
        RegistrationDate = GetRegistrationDate(decode_filepath);//注册时间
        TimeSpan span = DateTime.Now.Subtract(RegistrationDate);
        int days = Math.Abs(span.Days);
        if (days <= time_days)
        {
            tips = "试用期还剩" + (time_days - days).ToString() + "天,";
            IsShowTips = true;
            IsQuit = false;
            SetLastUseTime(decode_filepath);
        }
        else
        {
            tips = "试用期结束,";
            SetUsefulFalse(decode_filepath);
            IsQuit = true;
            IsShowTips = false;
            return;
        }


    }
    IEnumerator GenerateEncodeXML()
    {
        yield return new WaitForSeconds(1.0f);
        fileEncryption(original_filepath, "assets");
        if (File.Exists(encode_filepath))
        {
            File.Delete(original_filepath);
        }
    }
    void GenerateEncodeXML1(string filepath)
    {
        fileEncryption(filepath, "assets");
        if (File.Exists(encode_filepath))
        {
            File.Delete(filepath);
        }
    }
    //加密xml文件
    private void Encrypt(XmlDocument doc, string ElementName, SymmetricAlgorithm key)
    {
        XmlElement elementEncrypt = doc.GetElementsByTagName(ElementName)[0] as XmlElement;
        EncryptedXml eXml = new EncryptedXml();
        byte[] encryptElement = eXml.EncryptData(elementEncrypt, key, false);//
        EncryptedData edElement = new EncryptedData();
        edElement.Type = EncryptedXml.XmlEncElementUrl;
        string encryptionMethod = null;

        if (key is TripleDES)
        {
            encryptionMethod = EncryptedXml.XmlEncTripleDESUrl;
        }
        else if (key is DES)
        {
            encryptionMethod = EncryptedXml.XmlEncDESUrl;
        }

        if (key is Rijndael)
        {
            switch (key.KeySize)
            {
                case 128:
                    encryptionMethod = EncryptedXml.XmlEncAES128Url;
                    break;
                case 192:
                    encryptionMethod = EncryptedXml.XmlEncAES192Url;
                    break;
                case 256:
                    encryptionMethod = EncryptedXml.XmlEncAES256Url;
                    break;
            }
        }
        edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
        edElement.CipherData.CipherValue = encryptElement;
        EncryptedXml.ReplaceElement(elementEncrypt, edElement, false);
    }

    //XML文件解密
    private void Decrypt(XmlDocument doc, SymmetricAlgorithm Alg)
    {
        XmlElement encryptedElement = doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
        EncryptedData edElement = new EncryptedData();
        edElement.LoadXml(encryptedElement);
        EncryptedXml exml = new EncryptedXml();
        byte[] rgbOutput = exml.DecryptData(edElement, Alg);
        exml.ReplaceData(encryptedElement, rgbOutput);
    }


    //举例,对某个XML文件加密
    private void fileEncryption(string filename,string ElementName)
    {
        RijndaelManaged key = new RijndaelManaged();
        //设置密钥:key为32位=数字或字母16个=汉子8个
        byte[] byteKey = Encoding.Unicode.GetBytes("1111111111111111");
        key.Key = byteKey;
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.PreserveWhitespace = true;
        xmldoc.Load(filename);//想要加密的xml文件
        Encrypt(xmldoc, ElementName, key);//需要加密的节点
        if (key != null)
        {
            key.Clear();
        }
        xmldoc.Save(encode_filepath);//生成加密后的xml文件
    }
    //举例,对某个xml文件解密
    private void fileDcryption(string filename)
    {
        RijndaelManaged key = new RijndaelManaged();
        byte[] byteKey = Encoding.Unicode.GetBytes("1111111111111111");
        key.Key = byteKey;
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.PreserveWhitespace = true;
        xmldoc.Load(encode_filepath);//加载要解密的xml文件
        Decrypt(xmldoc, key);
        if (key != null)
        {
            key.Clear();
        }
        xmldoc.Save(decode_filepath);//生成解密后的文件
    }
}