//ライセンス情報はAgeOnフォルダのLISENCEフォルダを参照してください

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Diagnostics;
using Microsoft.VisualBasic.FileIO;

namespace AgeOnUpdate
{
    class UpdateFileData
    {
        public int versionNum = 0;
        public string fileName = "";
        public string folderName = "";
        public string fileUrl = "";
        public int fileSize = 0;
        public string message = "";

        public UpdateFileData()
        {
        }
    }

    class GetUpdateFile
    {
        public ProgressBarForm progressBarForm;

        private bool stoppingBool;

        int progressMax = 0;

        public static Mutex mutex = new Mutex(false, "GetBoardIndex");

        public string fileAddress = "";


        public GetUpdateFile()
        {
            stoppingBool = false;
            Const.GetMainDir();
            
            if (true)
            {
                try
                {
                    //現在の情報ファイルを得る
                    UpdateFileData nowFileData = new UpdateFileData();
                    string nowFileDataStr = FileIO.ReadShiftJis("update", "update.txt");
                    if (GetFileData(nowFileData, nowFileDataStr) == false)
                        return;

                    //アップデートをチェックする
                    string downloadStr = "";
                    if (DownloadCheckFile(ref downloadStr) == false)
                        return;

                    UpdateFileData updateFileData = new UpdateFileData();
                    //アップデートの情報ファイルを得る
                    if (GetFileData(updateFileData, downloadStr) == false)
                        return;

                    //現在の情報ファイルとアップデートの情報ファイルを比べる
                    if (ComparerUpDateFileData(nowFileData, updateFileData) == false)
                        return;


                    //ファイルのアップデートを始める


                    progressBarForm = new ProgressBarForm();
                    //progressBarForm.SetUpTwo();
                    Thread t = new Thread(new ThreadStart(progressBarForm.SetUpTwo));
                    t.IsBackground = true;
                    t.Start();

                    AgeOnControl.CloseAgeOn();

                    Thread.Sleep(1000);
                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.progressBar.Maximum = 110));

                    //受信
                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.textLabel.Text = "ファイルを受信しています"));

                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.progressBar.Value = 1));

                    //ファイルをダウンロードする
                    if (DownloadFile(updateFileData) == false)
                        return;

                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.textLabel.Text = "解凍しています"));
                    //解凍する
                    if (UnZipUpdateFile(updateFileData) == false)
                        return;

                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.textLabel.Text = "コピーしています"));
                    //コピーする
                    if (CopyUpdateFile(updateFileData) == false)
                        return;

                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.progressBar.Value = 110));
                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.textLabel.Text = "アップデートに成功しました"));

                    FileIO.SaveShiftJis("update", "update.txt", downloadStr);

                    System.Threading.Thread.Sleep(1000);

                    //AgeOnを開始する
                    AgeOnControl.StartAgeOn();

                    return;
                }
                catch
                {
                    progressBarForm.popUp.Invoke((Action)(() => progressBarForm.textLabel.Text = "アップデートに失敗しました"));
                    System.Threading.Thread.Sleep(1000);
                }
           
            }
        }
        public bool ComparerUpDateFileData(UpdateFileData nowFileData, UpdateFileData updateFileData)
        {
            if (nowFileData.versionNum < updateFileData.versionNum)
                return true;
            else if (updateFileData.versionNum == 0)
                return true;
            else
                return false;
        }
        public bool CopyUpdateFile(UpdateFileData updateFileData)
        {
            string updateFolder = Const.CurrentDir + Path.DirectorySeparatorChar + "update" + Path.DirectorySeparatorChar + updateFileData.folderName;
            //フォルダの中身をコピー
            //ディレクトリ一覧を列挙してコピー

            if (System.IO.Directory.Exists(updateFolder) == false)
            {
                return false;
            }

            string[] subFolders = Directory.GetDirectories(updateFolder, "*", System.IO.SearchOption.TopDirectoryOnly);

            if (subFolders.Length == 0)
                return false;

            foreach (string folder in subFolders)
            {
                string dstDir = Path.GetFileName(folder);

                Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
                    folder,
                    Const.CurrentDir + Path.DirectorySeparatorChar + dstDir,
                    Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
                    Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing);
            }

            string[] files = Directory.GetFiles(updateFolder);

            foreach (string file in files)
            {
                if (file.EndsWith("AgeOnUpdate.exe") == true)
                {
                    FileSystem.CopyFile(file, Const.CurrentDir + Path.DirectorySeparatorChar + "_AgeOnUpdate.exe", true);
                    continue;
                }
                if (file.EndsWith("Thumbs.db") == true)
                    continue;
                if (file.EndsWith("ICSharpCode.SharpZipLib.dll") == true)
                    continue;
                
                string dstFile = Const.CurrentDir + Path.DirectorySeparatorChar + Path.GetFileName(file);

                FileSystem.CopyFile(file, dstFile, true);
            }
            return true;
        }
        //参考：http://dobon.net/vb/dotnet/links/sharpziplib.html
        public bool UnZipUpdateFile(UpdateFileData updateFileData)
        {
            //展開するZIP書庫のパス
            string zipFileName = "update" + Path.DirectorySeparatorChar + updateFileData.fileName; 

            //展開したファイルを保存するフォルダ（存在しないと作成される）
            string targetDirectory = Const.CurrentDir + 
                Path.DirectorySeparatorChar + "update";

            //展開するファイルのフィルタ
            string fileFilter = "";

            //FastZipオブジェクトの作成
            ICSharpCode.SharpZipLib.Zip.FastZip fastZip =
                new ICSharpCode.SharpZipLib.Zip.FastZip();

            //属性を復元するか。デフォルトはfalse
            fastZip.RestoreAttributesOnExtract = true;

            //ファイル日時を復元するか。デフォルトはfalse
            fastZip.RestoreDateTimeOnExtract = true;

            //空のフォルダも作成するか。デフォルトはfalse
            fastZip.CreateEmptyDirectories = true;

            //ZIP書庫を展開する
            try
            {
                fastZip.ExtractZip(zipFileName, targetDirectory, fileFilter);
            }
            catch
            { ;}
            return true;
        }

        public bool GetFileData(UpdateFileData updateFileData, string downloadStr)
        {
            string[] data = downloadStr.Split(',');
            int a = 0;
            
            //整数でなければfalse
            if (Int32.TryParse(data[0], out a) == false)
                return false;
            updateFileData.versionNum = Int32.Parse(data[0]);
            
            //AgeOnで始まってなければfalse
            if (data[1].StartsWith("AgeOn") == false)
                return false;
            updateFileData.fileName = data[1];
            updateFileData.folderName = data[1].Substring(0, data[1].Length - 4);
            updateFileData.fileUrl = "http://maedanaoki.jp/software/ageon/" + data[1];

            //int型にできなければfalse
            if (Int32.TryParse(data[2],out a) == false)
                return false;
            updateFileData.fileSize = Int32.Parse(data[2]);

            //長さが０ならfalse
            if (data[3].Length == 0)
                return false;
            updateFileData.message = data[3];

            return true;
        }

        public bool DownloadCheckFile(ref string downloadStr)
        {
            DownloadUpdateCheckFile ddk = new DownloadUpdateCheckFile();
            if (true == ddk.Download(Const.UPDATE_CHECK_URL))
            {
                downloadStr = ddk.httpResData;
                //FileIO.SaveShiftJis("update", "update.txt", downloadStr);
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool DownloadFile(UpdateFileData updateFileData)
        {
            try
            {
                DownloadBinary downloadBinary = new DownloadBinary();
                byte[] data = downloadBinary.DownloadBinaryMethod(updateFileData, progressBarForm);

                if (data == null)
                {
                    return false;
                }
                else
                    ;

                File.WriteAllBytes(Const.CurrentDir + 
                    Path.DirectorySeparatorChar + "update" +
                    Path.DirectorySeparatorChar + updateFileData.fileName, data);

                return true;
            }
            catch (System.Exception ex)
            {
                return false;
            }
        }
    }
}
