/*
 * 由SharpDevelop创建。
 * 用户： Acer
 * 日期: 2014-10-12
 * 时间: 19:43
 * 
 */
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Windows.Forms;
using System.ComponentModel;

using DataEditorX.Language;
using DataEditorX.Common;
using DataEditorX.Config;

namespace DataEditorX.Core
{
    public enum MyTask
    {
        NONE,
        CheckUpdate,
        ExportData,
        SaveAsMSE,
        CutImages,
        ConvertImages,
    }
    /// <summary>
    /// Description of TaskHelper.
    /// </summary>
    public class TaskHelper
    {
        #region Member
        private MyTask nowTask = MyTask.NONE;
        private MyTask lastTask = MyTask.NONE;
        private Card[] cardlist;
        private string[] mArgs;
        private ImageSet imgSet = new ImageSet();
        private MseMaker mseHelper;
        private bool isCancel = false;
        private bool isRun = false;
        private BackgroundWorker worker;

        public TaskHelper(string datapath, BackgroundWorker worker, MSEConfig mcfg)
        {
            this.worker = worker;
            mseHelper = new MseMaker(mcfg);
            imgSet.Init();
        }
        public MseMaker MseHelper
        {
            get { return mseHelper; }
        }
        public bool IsRuning()
        {
            return isRun;
        }
        public bool IsCancel()
        {
            return isCancel;
        }
        public void Cancel()
        {
            isCancel = true;
        }
        public MyTask getLastTask()
        {
            return lastTask;
        }
        #endregion

        #region Other
        public void SetTask(MyTask myTask, Card[] cards, params string[] args)
        {
            nowTask = myTask;
            cardlist = cards;
            mArgs = args;
        }
        public void ToImg(string img, string saveimg1, string saveimg2)
        {
            if (!File.Exists(img))
                return;
            Bitmap bmp = new Bitmap(img);
            MyBitmap.SaveAsJPEG(MyBitmap.Zoom(bmp, imgSet.W, imgSet.H),
                                saveimg1, imgSet.quilty);
            MyBitmap.SaveAsJPEG(MyBitmap.Zoom(bmp, imgSet.w, imgSet.h),
                                saveimg2, imgSet.quilty);
        }
        #endregion

        #region 检查更新
        public static void CheckVersion(bool showNew)
        {
            string newver = CheckUpdate.Check(MyConfig.readString(MyConfig.TAG_UPDATE_URL));
            int iver, iver2;
            int.TryParse(Application.ProductVersion.Replace(".", ""), out iver);
            int.TryParse(newver.Replace(".", ""), out iver2);
            if (iver2 > iver)
            {//有最新版本
                if (!MyMsg.Question(LMSG.HaveNewVersion))
                    return;
            }
            else if (iver2 > 0)
            {//现在就是最新版本
                if (!showNew)
                    return;
                if (!MyMsg.Question(LMSG.NowIsNewVersion))
                    return;
            }
            else
            {//检查失败
                if (!showNew)
                    return;
                MyMsg.Error(LMSG.CheckUpdateFail);
                return;
            }
            if (CheckUpdate.DownLoad(
                MyPath.Combine(Application.StartupPath, newver + ".zip")))
                MyMsg.Show(LMSG.DownloadSucceed);
            else
                MyMsg.Show(LMSG.DownloadFail);
        }
        public void OnCheckUpdate(bool showNew)
        {
            TaskHelper.CheckVersion(showNew);
        }
        #endregion

        #region 裁剪图片
        public void CutImages(string imgpath, bool isreplace)
        {
            int count = cardlist.Length;
            int i = 0;
            foreach (Card c in cardlist)
            {
                if (isCancel)
                    break;
                i++;
                worker.ReportProgress((i / count), string.Format("{0}/{1}", i, count));
                string jpg = MyPath.Combine(imgpath, c.id + ".jpg");
                string savejpg = MyPath.Combine(mseHelper.ImagePath, c.id + ".jpg");
                if (File.Exists(jpg) && (isreplace || !File.Exists(savejpg)))
                {
                    Bitmap bp = new Bitmap(jpg);
                    Bitmap bmp = null;
                    if (c.IsType(CardType.TYPE_XYZ))
                    {
                        bmp = MyBitmap.Cut(bp, imgSet.xyzArea);
                    }
                    else if (c.IsType(CardType.TYPE_PENDULUM))
                    {
                        bmp = MyBitmap.Cut(bp, imgSet.pendulumArea);
                    }
                    else
                    {
                        bmp = MyBitmap.Cut(bp, imgSet.normalArea);
                    }
                    MyBitmap.SaveAsJPEG(bmp, savejpg, imgSet.quilty);
                    //bmp.Save(savejpg, ImageFormat.Png);
                }
            }
        }
        #endregion
        
        #region 转换图片
        public void ConvertImages(string imgpath, string gamepath, bool isreplace)
        {
            string picspath = MyPath.Combine(gamepath, "pics");
            string thubpath = MyPath.Combine(picspath, "thumbnail");
            string[] files = Directory.GetFiles(imgpath);
            int i = 0;
            int count = files.Length;

            foreach (string f in files)
            {
                if (isCancel)
                    break;
                i++;
                worker.ReportProgress(i / count, string.Format("{0}/{1}", i, count));
                string ex = Path.GetExtension(f).ToLower();
                string name = Path.GetFileNameWithoutExtension(f);
                string jpg_b = MyPath.Combine(picspath, name + ".jpg");
                string jpg_s = MyPath.Combine(thubpath, name + ".jpg");
                if (ex == ".jpg" || ex == ".png" || ex == ".bmp")
                {
                    if (File.Exists(f))
                    {
                        //存在大图
                        Bitmap bmp = new Bitmap(f);
                        if (isreplace || !File.Exists(jpg_b))
                        {

                            MyBitmap.SaveAsJPEG(MyBitmap.Zoom(bmp, imgSet.W, imgSet.H),
                                                jpg_b, imgSet.quilty);
                        }
                        if (isreplace || !File.Exists(jpg_s))
                        {
                            MyBitmap.SaveAsJPEG(MyBitmap.Zoom(bmp, imgSet.w, imgSet.h),
                                                jpg_s, imgSet.quilty);

                        }
                    }
                }
            }
        }
        #endregion

        #region MSE存档
        public string MSEImage
        {
            get { return mseHelper.ImagePath; }
        }
        public void SaveMSEs(string file, Card[] cards, bool isUpdate)
        {
            if (mseHelper.MaxNum == 0)
                SaveMSE(1, file, cards, isUpdate);
            else
            {
                int c = cards.Length;
                int nums = c / mseHelper.MaxNum;
                if (nums * mseHelper.MaxNum < c)
                    nums++;
                List<Card> clist = new List<Card>();
                for (int i = 0; i < nums; i++)
                {
                    clist.Clear();
                    for (int j = 0; j < mseHelper.MaxNum; j++)
                    {
                        int index = i * mseHelper.MaxNum + j;
                        if (index < c)
                            clist.Add(cards[index]);
                    }
                    int t = file.LastIndexOf(".mse-set");
                    string fname = (t > 0) ? file.Substring(0, t) : file;
                    fname = fname + string.Format("_{0}.mse-set", i + 1);
                    SaveMSE(i + 1, fname, clist.ToArray(), isUpdate);
                }
            }
        }
        public void SaveMSE(int num, string file, Card[] cards, bool isUpdate)
        {
            string setFile = file + ".txt";
            string[] images = mseHelper.WriteSet(setFile, cards);
            if (isUpdate)//仅更新文字
                return;
            int i = 0;
            int count = images.Length;
            using (ZipStorer zips = ZipStorer.Create(file, ""))
            {
                zips.EncodeUTF8 = true;
                zips.AddFile(setFile, "set", "");
                foreach (string img in images)
                {
                    if (isCancel)
                        break;
                    i++;
                    worker.ReportProgress(i / count, string.Format("{0}/{1}-{2}", i, count, num));
                    zips.AddFile(img, Path.GetFileName(img), "");
                }
            }
            File.Delete(setFile);
        }
        #endregion

        #region 导出数据
        public void ExportData(string zipname)
        {
            int i = 0;
            Card[] cards = cardlist;
            if (cards == null || cards.Length == 0)
                return;
            int count = cards.Length;
            string path = Path.GetDirectoryName(zipname);
            string name = Path.GetFileNameWithoutExtension(zipname);
            string cdbfile = zipname + ".cdb";
            string readme = MyPath.Combine(path, name + ".txt");
            string deckydk = MyPath.Combine(path, "deck/" + name + ".ydk");
            string pics = MyPath.Combine(path, "pics");
            string thumb = MyPath.Combine(pics, "thumbnail");
            string script = MyPath.Combine(path, "script");

            File.Delete(cdbfile);
            DataBase.Create(cdbfile);
            DataBase.CopyDB(cdbfile, false, cardlist);

            if (File.Exists(zipname))
                File.Delete(zipname);
            using (ZipStorer zips = ZipStorer.Create(zipname, ""))
            {
                zips.AddFile(cdbfile, name + ".cdb", "");
                if (File.Exists(readme))
                    zips.AddFile(readme, "readme_" + name + ".txt", "");
                if (File.Exists(deckydk))
                    zips.AddFile(deckydk, "deck/" + name + ".ydk", "");
                foreach (Card c in cards)
                {
                    i++;
                    worker.ReportProgress(i / count, string.Format("{0}/{1}", i, count));
                    //zips.AddFile(
                    string jpg1 = MyPath.Combine(pics, c.id.ToString() + ".jpg");
                    string jpg2 = MyPath.Combine(thumb, c.id.ToString() + ".jpg");
                    string lua = MyPath.Combine(script, "c" + c.id.ToString() + ".lua");

                    if (File.Exists(jpg1))
                        zips.AddFile(jpg1, "pics/" + c.id.ToString() + ".jpg", "");
                    if (File.Exists(jpg2))
                        zips.AddFile(jpg2, "pics/thumbnail/" + c.id.ToString() + ".jpg", "");
                    if (File.Exists(lua))
                        zips.AddFile(lua, "script/c" + c.id.ToString() + ".lua", "");
                }
            }
            File.Delete(cdbfile);
        }
        #endregion

        #region 运行
        public void Run()
        {
            isCancel = false;
            isRun = true;
            bool replace;
            bool showNew;
            switch (nowTask)
            {
                case MyTask.ExportData:
                    if (mArgs != null && mArgs.Length >= 1)
                    {
                        ExportData(mArgs[0]);
                    }
                    break;
                case MyTask.CheckUpdate:
                    showNew = false;
                    if (mArgs != null && mArgs.Length >= 1)
                    {
                        showNew = (mArgs[0] == Boolean.TrueString) ? true : false;
                    }
                    OnCheckUpdate(showNew);
                    break;
                case MyTask.CutImages:
                    if (mArgs != null && mArgs.Length >= 2)
                    {
                        replace = true;
                        if (mArgs.Length >= 2)
                        {
                            if (mArgs[1] == Boolean.FalseString)
                                replace = false;
                        }
                        CutImages(mArgs[0], replace);
                    }
                    break;
                case MyTask.SaveAsMSE:
                    if (mArgs != null && mArgs.Length >= 2)
                    {
                        replace = false;
                        if (mArgs.Length >= 2)
                        {
                            if (mArgs[1] == Boolean.TrueString)
                                replace = true;
                        }
                        SaveMSEs(mArgs[0], cardlist, replace);
                    }
                    break;
                case MyTask.ConvertImages:
                    if (mArgs != null && mArgs.Length >= 2)
                    {
                        replace = true;
                        if (mArgs.Length >= 3)
                        {
                            if (mArgs[2] == Boolean.FalseString)
                                replace = false;
                        }
                        ConvertImages(mArgs[0], mArgs[1], replace);
                    }
                    break;
            }
            isRun = false;
            lastTask = nowTask;
            nowTask = MyTask.NONE;
            cardlist = null;
            mArgs = null;
        }
        #endregion
    }

}
