using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NPOI.HSSF.UserModel;
using CommonLang.Xml;
using System.Xml;
using CommonLang.Concurrent;
using CommonLang.XCSV;

namespace GameEditorPlugin.Utils
{
    public class XLS2XCSV
    {
        public readonly XCSVMeta Meta;
        public XmlDocument Doc { get { return Meta.Doc; } }
        public FileInfo XlsFile { get { return Meta.XlsFile; } }
        public float Percent { get { lock (this) { return mReaded / (float)mTotal; } } }

        private HSSFWorkbook Workbook;
        private int mTotal = 1;
        private int mReaded = 0;

        public XLS2XCSV(FileInfo ff)
        {
            lock (this)
            {
                Meta.Doc = new XmlDocument();
                Meta.XlsFile = ff;
                this.mTotal = 0; 
                using (FileStream ms = new FileStream(XlsFile.FullName, FileMode.Open, FileAccess.Read))
                {
                    Workbook = new HSSFWorkbook(ms);
                    for (int si = 0; si < Workbook.NumberOfSheets; si++)
                    {
                        HSSFSheet sheet = Workbook.GetSheetAt(si) as HSSFSheet;
                        mTotal += (sheet.LastRowNum - sheet.FirstRowNum + 1);
                    }
                }
            }
        }

        public void Load(AtomicFloat percent = null)
        {
            float d = 1f / mTotal;
            XmlElement xml = Doc.CreateElement("workbook");
            xml.SetAttribute("name", XlsFile.Name);
            this.Doc.AppendChild(xml);
            for (int si = 0; si < Workbook.NumberOfSheets; si++)
            {
                HSSFSheet sheet = Workbook.GetSheetAt(si) as HSSFSheet;
                XmlElement xsheet = Doc.CreateElement("sheet");
                xsheet.SetAttribute("name", sheet.SheetName);
                for (int r = sheet.FirstRowNum; r <= sheet.LastRowNum; r++)
                {
                    HSSFRow row = sheet.GetRow(r) as HSSFRow;
                    if (row != null)
                    {
                        XmlElement xrow = Doc.CreateElement("row");
                        xrow.SetAttribute("r", r.ToString());
                        for (int c = row.FirstCellNum; c <= row.LastCellNum; c++)
                        {
                            HSSFCell cell = row.GetCell(c) as HSSFCell;
                            if (cell != null)
                            {
                                XmlElement xcell = Doc.CreateElement("cell");
                                xcell.InnerText = cell.ToString();
                                xcell.SetAttribute("r", r.ToString());
                                xcell.SetAttribute("c", c.ToString());
                                xrow.AppendChild(xcell);
                            }
                        }
                        xsheet.AppendChild(xrow);
                    }
                    mReaded += 1;
                    if (percent != null)
                    {
                        percent.AddAndGet(d);
                    }
                }
                xml.AppendChild(xsheet);
            }
        }

        public void Save()
        {
            Save(XlsFile.Directory + "/" + Path.GetFileNameWithoutExtension(XlsFile.FullName) + ".xcsv");
        }

        public void Save(string path)
        {
            XmlUtil.SaveXML(new FileStream(path, FileMode.Create, FileAccess.Write), Doc, true);
        }
    }
}