using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using ICSharpCode.SharpZipLib.Zip;
using UnityEngine;


public class UnZipThread
{
    public Thread thread;
    private UnZipThreadPool unZipThreadPool;
    private string unPath;


   

    private byte[] zipData = new byte[2048];
    public bool isUnEnd;
    private bool isUpdateEnd;

    public void InitUnZip(UnZipThreadPool unZipThreadPool)
    {
        this.unZipThreadPool = unZipThreadPool;
        unPath = unZipThreadPool.unPath;
   
        isUpdateEnd = true;
        thread = new Thread(ThreadUpdate);
        thread.Start();
    }

    private void ThreadUpdate()
    {
        while (isUpdateEnd)
        {
            try
            {
                ZipEntry ze = null;
                Stream stream = null;
                lock (unZipThreadPool.allZipFile)
                {
                    if (unZipThreadPool.allZipFile.Count > 0)
                    {
                        ze = unZipThreadPool.allZipFile[0];
                        unZipThreadPool.allZipFile.Remove(ze);
                        stream = unZipThreadPool.zipFile.GetInputStream(ze);
                    }
                }
                if (ze == null)
                {
                    Thread.Sleep(1000);
                    return;
                }

                isUnEnd = false;
                UnzipFile(ze, stream, unPath);
               
            }
            catch (Exception e)
            {
                Debug.LogError("解压失败");
            }
            isUnEnd = true;
            Thread.Sleep(10);
        }
    }

    public void Cloas()
    {
        isUpdateEnd = false;
        thread = null;
    }


    private void UnzipFile(ZipEntry zip, Stream stream, string dirPath)
    {
        FileStream fileStream = null;
        try
        {
            //文件名不为空  
            if (!string.IsNullOrEmpty(zip.Name))
            {
                string filePath = dirPath;
                string[] files = zip.Name.Split('/');
                // if (files.Length < 2)
                // {
                //     return;
                // }

                filePath += "/" + files[files.Length - 1];


                //如果是一个新的文件路径　这里需要创建这个文件路径  
                if (IsDirectory(filePath))
                {
                    Debug.Log("Create  file paht " + filePath);
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                }
                else
                {
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                    }

                    fileStream = File.Create(filePath);

                    // Debug.Log(filePath);
                    // MemoryStream ms = new MemoryStream();

                    int size = 0;

                    //每次读取2MB  直到把这个内容读完  
                    while (true)
                    {
                        size = stream.Read(zipData, 0, zipData.Length);
                        //小于0， 也就读完了当前的流  
                        if (size > 0)
                        {
                            unZipThreadPool.currSize += size;
                            fileStream.Write(zipData, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }

                    fileStream.Flush();
                    fileStream.Close();
                    fileStream.Dispose();
                    fileStream = null;
                 
                }
            }
        }
        catch (Exception e)
        {
            if (fileStream != null)
            {
                fileStream.Close();
                fileStream.Dispose();
            }

            fileStream = null;

            Debug.LogError("解压错误" + zip.Name);
            Debug.Log(e);
        }
    }

    /// <summary>  
    /// 判断是否是目录文件  
    /// </summary>  
    /// <param name="path"></param>  
    /// <returns></returns>  
    private bool IsDirectory(string path)
    {
        if (path[path.Length - 1] == '/')
        {
            return true;
        }

        return false;
    }
}

public class UnZipThreadPool
{
   
    public string unPath;

    public float jd
    {
        get { return currSize / maxSize; }
    }

    public float currSize;

    public bool isEnd
    {
        get
        {
            bool isCount = false;
            lock (allZipFile)
            {
                if (allZipFile.Count <= 0)
                {
                    isCount = true;
                }
            }

            if (isCount)
            {
                for (int i = 0; i < _zipThreads.Count; i++)
                {
                    if (!_zipThreads[i].isUnEnd)
                    {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }
    }

    public float maxSize;
  
    public ZipFile zipFile;

    public List<ZipEntry> allZipFile = new List<ZipEntry>();
    private List<UnZipThread> _zipThreads = new List<UnZipThread>();

    public int CurrCount()
    {
        lock (allZipFile)
        {
            return allZipFile.Count;
        }
    }

    private FileStream fileStream;
    public void InitUnZip(byte[] zipData, string unPath)
    {
   
        this.unPath = unPath;
        maxSize = zipData.Length;
        MemoryStream ms = new MemoryStream(zipData);
        zipFile = new ZipFile(ms);
        IEnumerator ie = zipFile.GetEnumerator();
        while (ie.MoveNext())
        {
            allZipFile.Add((ZipEntry) ie.Current);
        }

        for (int i = 0; i < 8; i++)
        {
            UnZipThread u = new UnZipThread();
            u.InitUnZip(this);
            _zipThreads.Add(u);
        }
    }
    public void InitUnZip(string filePath, string unPath)
    {
      
        if (!Directory.Exists(unPath))
        {
            Directory.CreateDirectory(unPath);
        }
        this.unPath = unPath;
         fileStream = new FileStream(filePath, FileMode.Open);
        zipFile = new ZipFile(fileStream);
        IEnumerator ie = zipFile.GetEnumerator();
        while (ie.MoveNext())
        {
            allZipFile.Add((ZipEntry) ie.Current);
        }

        maxSize = allZipFile.Count;
        for (int i = 0; i < 4; i++)
        {
            UnZipThread u = new UnZipThread();
            u.InitUnZip(this);
            _zipThreads.Add(u);
        }
    }
   

    public void Cloas()
    {
        for (int i = 0; i < _zipThreads.Count; i++)
        {
            _zipThreads[i].Cloas();
        }

        if (fileStream != null)
        {
            fileStream.Close();
            fileStream.Dispose();
        }
        allZipFile.Clear();

        fileStream = null;
    }

    // public void UnzipWithPath()
    // {
    //     Debug.Log("dirpath is:" + unPath);
    //     //ZipEntry：文件条目 就是该目录下所有的文件列表(也就是所有文件的路径)  
    //     ZipEntry zip = null;
    //     //输入的所有的文件流都是存储在这里面的  
    //     ZipInputStream zipInStream = null;
    //    
    //     MemoryStream ms = new MemoryStream(zipData);
    //
    //     //读取文件流到zipInputStream  
    //     zipInStream = new ZipInputStream(ms);
    //
    //     int topSize = zipData.Length;
    //
    //     int countCount = 0;
    //
    //     //循环读取Zip目录下的所有文件  
    //     while ((zip = zipInStream.GetNextEntry()) != null)
    //     {
    //         //  Debug.Log("name is:"   zip.Name   " zipStream "   zipInStream);  
    //         UnzipFile(zip, zipInStream, unPath);
    //         countCount++;
    //         jd = currSize * 1.0f / topSize;
    //         if (countCount > 20)
    //         {
    //             countCount = 0;
    //             Thread.Sleep(10);
    //         }
    //     }
    //
    //     zipInStream.Close();
    //     isEnd = true;
    // }
    //
    // private void UnzipFile(ZipEntry zip, ZipInputStream zipInStream, string dirPath)
    // {
    //     try
    //     {
    //         //文件名不为空  
    //         if (!string.IsNullOrEmpty(zip.Name))
    //         {
    //             string filePath = dirPath;
    //             string[] files = zip.Name.Split('/');
    //             if (files.Length < 2)
    //             {
    //                 return;
    //             }
    //
    //             filePath += "/" + files[files.Length - 1];
    //          
    //
    //             //如果是一个新的文件路径　这里需要创建这个文件路径  
    //             if (IsDirectory(filePath))
    //             {
    //                 Debug.Log("Create  file paht " + filePath);
    //                 if (!Directory.Exists(filePath))
    //                 {
    //                     Directory.CreateDirectory(filePath);
    //                 }
    //             }
    //             else
    //             {
    //                 MemoryStream ms = new MemoryStream();
    //
    //                 int size = 0;
    //
    //                 //每次读取2MB  直到把这个内容读完  
    //                 while (true)
    //                 {
    //                     size = zipInStream.Read(zipData, 0, zipData.Length);
    //                     //小于0， 也就读完了当前的流  
    //                     if (size > 0)
    //                     {
    //                         currSize += size;
    //                         ms.Write(zipData, 0, size);
    //                     }
    //                     else
    //                     {
    //                         break;
    //                     }
    //                 }
    //
    //                 ms.Flush();
    //                 byte[] fileData = ms.ToArray();
    //                 File.WriteAllBytes(filePath, fileData);
    //                 if (zip.Name.Contains("md5File"))
    //                 {
    //                     File.WriteAllBytes(md5Path, fileData);
    //                 }
    //
    //                 ms.Close();
    //                 ms.Dispose();
    //             }
    //         }
    //     }
    //     catch (Exception e)
    //     {
    //         Debug.LogError("解压错误"+zip.Name);
    //         Debug.Log(e);
    //     }
    // }
    //
    // /// <summary>  
    // /// 判断是否是目录文件  
    // /// </summary>  
    // /// <param name="path"></param>  
    // /// <returns></returns>  
    // private bool IsDirectory(string path)
    // {
    //     if (path[path.Length - 1] == '/')
    //     {
    //         return true;
    //     }
    //
    //     return false;
    // }
}