/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan K�llman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied.
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 *
 * Author							Change						Date
 * ******************************************************************************
 * Jan K�llman		    Initial Release		        2009-10-01
 * Jan K�llman		    License changed GPL-->LGPL 2011-12-27
 *******************************************************************************/

using System;
using System.Linq;
using System.Xml;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.Style;
using OfficeOpenXml.Style.Dxf;
using OfficeOpenXml.Style.XmlAccess;

namespace OfficeOpenXml;

/// <summary>
/// Containts all shared cell styles for a workbook
/// </summary>
public sealed class ExcelStyles : XmlHelper {
  private const string _numberFormatsPath = "d:styleSheet/d:numFmts";
  private const string _fontsPath = "d:styleSheet/d:fonts";
  private const string _fillsPath = "d:styleSheet/d:fills";
  private const string _bordersPath = "d:styleSheet/d:borders";
  private const string _cellStyleXfsPath = "d:styleSheet/d:cellStyleXfs";
  private const string _cellXfsPath = "d:styleSheet/d:cellXfs";
  private const string _cellStylesPath = "d:styleSheet/d:cellStyles";
  private const string _dxfsPath = "d:styleSheet/d:dxfs";

  //internal Dictionary<int, ExcelXfs> Styles = new Dictionary<int, ExcelXfs>();
  private readonly XmlDocument _styleXml;
  private readonly ExcelWorkbook _wb;
  private readonly XmlNamespaceManager _nameSpaceManager;
  internal int _nextDfxNumFmtID = 164;

  internal ExcelStyles(XmlNamespaceManager nameSpaceManager, XmlDocument xml, ExcelWorkbook wb)
      : base(nameSpaceManager, xml) {
    _styleXml = xml;
    _wb = wb;
    _nameSpaceManager = nameSpaceManager;
    SchemaNodeOrder = new[] {
      "numFmts",
      "fonts",
      "fills",
      "borders",
      "cellStyleXfs",
      "cellXfs",
      "cellStyles",
      "dxfs",
    };
    LoadFromDocument();
  }

  /// <summary>
  /// Loads the style XML to memory
  /// </summary>
  private void LoadFromDocument() {
    //NumberFormats
    ExcelNumberFormatXml.AddBuildIn(NameSpaceManager, NumberFormats);
    XmlNode numNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager);
    if (numNode != null) {
      foreach (XmlNode n in numNode) {
        ExcelNumberFormatXml nf = new ExcelNumberFormatXml(_nameSpaceManager, n);
        NumberFormats.Add(nf.Id, nf);
        if (nf.NumFmtId >= NumberFormats.NextId) {
          NumberFormats.NextId = nf.NumFmtId + 1;
        }
      }
    }

    //Fonts
    XmlNode fontNode = _styleXml.SelectSingleNode(_fontsPath, _nameSpaceManager);
    foreach (XmlNode n in fontNode) {
      ExcelFontXml f = new ExcelFontXml(_nameSpaceManager, n);
      Fonts.Add(f.Id, f);
    }

    //Fills
    XmlNode fillNode = _styleXml.SelectSingleNode(_fillsPath, _nameSpaceManager);
    foreach (XmlNode n in fillNode) {
      ExcelFillXml f;
      if (n.FirstChild != null && n.FirstChild.LocalName == "gradientFill") {
        f = new ExcelGradientFillXml(_nameSpaceManager, n);
      } else {
        f = new(_nameSpaceManager, n);
      }
      Fills.Add(f.Id, f);
    }

    //Borders
    XmlNode borderNode = _styleXml.SelectSingleNode(_bordersPath, _nameSpaceManager);
    foreach (XmlNode n in borderNode) {
      ExcelBorderXml b = new ExcelBorderXml(_nameSpaceManager, n);
      Borders.Add(b.Id, b);
    }

    //cellStyleXfs
    XmlNode styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager);
    if (styleXfsNode != null) {
      foreach (XmlNode n in styleXfsNode) {
        ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this);
        CellStyleXfs.Add(item.Id, item);
      }
    }

    XmlNode styleNode = _styleXml.SelectSingleNode(_cellXfsPath, _nameSpaceManager);
    for (int i = 0; i < styleNode.ChildNodes.Count; i++) {
      XmlNode n = styleNode.ChildNodes[i];
      ExcelXfs item = new ExcelXfs(_nameSpaceManager, n, this);
      CellXfs.Add(item.Id, item);
    }

    //cellStyle
    XmlNode namedStyleNode = _styleXml.SelectSingleNode(_cellStylesPath, _nameSpaceManager);
    if (namedStyleNode != null) {
      foreach (XmlNode n in namedStyleNode) {
        ExcelNamedStyleXml item = new ExcelNamedStyleXml(_nameSpaceManager, n, this);
        NamedStyles.Add(item.Name, item);
      }
    }

    //dxfsPath
    XmlNode dxfsNode = _styleXml.SelectSingleNode(_dxfsPath, _nameSpaceManager);
    if (dxfsNode != null) {
      foreach (XmlNode x in dxfsNode) {
        ExcelDxfStyleConditionalFormatting item = new ExcelDxfStyleConditionalFormatting(
            _nameSpaceManager,
            x,
            this);
        Dxfs.Add(item.Id, item);
      }
    }
  }

  internal ExcelStyle GetStyleObject(int id, int positionId, string address) {
    if (id < 0) {
      id = 0;
    }
    return new(this, positionId, address, id);
  }

  internal int GetStyleId(ExcelWorksheet ws, int row, int col) {
    int v = 0;
    if (ws._styles.Exists(row, col, ref v)) {
      return v;
    }
    if (ws._styles.Exists(
        row,
        0,
        ref v)) //First Row
    {
      return v;
    } // then column
    if (ws._styles.Exists(0, col, ref v)) {
      return v;
    }
    int r = 0,
        c = col;
    if (ws._values.PrevCell(ref r, ref c)) {
      var column = ws._values.GetValue(0, c) as ExcelColumn;
      if (column != null
          && column.ColumnMax
              >= col) //Fixes issue 15174
      {
        return ws._styles.GetValue(0, c);
      }
      return 0;
    }
    return 0;
  }

  public ExcelStyleCollection<ExcelNumberFormatXml> NumberFormats = new();
  public ExcelStyleCollection<ExcelFontXml> Fonts = new();
  public ExcelStyleCollection<ExcelFillXml> Fills = new();
  public ExcelStyleCollection<ExcelBorderXml> Borders = new();
  public ExcelStyleCollection<ExcelXfs> CellStyleXfs = new();
  public ExcelStyleCollection<ExcelXfs> CellXfs = new();
  public ExcelStyleCollection<ExcelNamedStyleXml> NamedStyles = new();
  public ExcelStyleCollection<ExcelDxfStyleConditionalFormatting> Dxfs = new();

  internal string Id => "";

  public ExcelNamedStyleXml CreateNamedStyle(string name) {
    return CreateNamedStyle(name, null);
  }

  public ExcelNamedStyleXml CreateNamedStyle(string name, ExcelStyle template) {
    if (_wb.Styles.NamedStyles.ExistsKey(name)) {
      throw new(string.Format("Key {0} already exists in collection", name));
    }

    ExcelNamedStyleXml style;
    style = new(NameSpaceManager, this);
    int xfIdCopy,
        positionId;
    ExcelStyles styles;
    if (template == null) {
      //                style.Style = new ExcelStyle(this, NamedStylePropertyChange, -1, name, 0);
      xfIdCopy = 0;
      positionId = -1;
      styles = this;
    } else {
      if (template.PositionID < 0 && template.Styles == this) {
        xfIdCopy = template.Index;
        positionId = template.PositionID;
        styles = this;
        //style.Style = new ExcelStyle(this, NamedStylePropertyChange, Template.PositionID, name, Template.Index);
        //style.StyleXfId = Template.Index;
      } else {
        xfIdCopy = template.XfId;
        positionId = -1;
        styles = template.Styles;
      }
    }
    //Clone namedstyle
    int styleXfId = CloneStyle(styles, xfIdCopy, true);
    //Close cells style
    CellStyleXfs[styleXfId].XfId = CellStyleXfs.Count - 1;
    int xfid = CloneStyle(styles, xfIdCopy, false, true); //Always add a new style (We create a new named style here)
    CellXfs[xfid].XfId = styleXfId;
    style.Style = new(this, positionId, name, styleXfId);
    style.StyleXfId = styleXfId;

    style.Name = name;
    int ix = _wb.Styles.NamedStyles.Add(style.Name, style);
    style.Style.SetIndex(ix);
    //style.Style.XfId = ix;
    return style;
  }

  public void UpdateXml() {
    RemoveUnusedStyles();

    //NumberFormat
    XmlNode nfNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager);
    if (nfNode == null) {
      CreateNode(_numberFormatsPath, true);
      nfNode = _styleXml.SelectSingleNode(_numberFormatsPath, _nameSpaceManager);
    } else {
      nfNode.RemoveAll();
    }

    int count = 0;
    int normalIx = NamedStyles.FindIndexById("Normal");
    if (NamedStyles.Count > 0
        && normalIx >= 0
        && NamedStyles[normalIx].Style.Numberformat.NumFmtID >= 164) {
      ExcelNumberFormatXml nf = NumberFormats[NumberFormats.FindIndexById(
            NamedStyles[normalIx].Style.Numberformat.Id)];
      nfNode.AppendChild(
          nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage._schemaMain)));
      nf.newID = count++;
    }
    foreach (ExcelNumberFormatXml nf in NumberFormats) {
      if (!nf.BuildIn /*&& nf.newID<0*/) //Buildin formats are not updated.
      {
        nfNode.AppendChild(
            nf.CreateXmlNode(_styleXml.CreateElement("numFmt", ExcelPackage._schemaMain)));
        nf.newID = count;
        count++;
      }
    }
    (nfNode as XmlElement).SetAttribute("count", count.ToString());

    //Font
    count = 0;
    XmlNode fntNode = _styleXml.SelectSingleNode(_fontsPath, _nameSpaceManager);
    fntNode.RemoveAll();

    //Normal should be first in the collection
    if (NamedStyles.Count > 0 && normalIx >= 0 && NamedStyles[normalIx].Style.Font.Index > 0) {
      ExcelFontXml fnt = Fonts[NamedStyles[normalIx].Style.Font.Index];
      fntNode.AppendChild(
          fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage._schemaMain)));
      fnt.newID = count++;
    }

    foreach (ExcelFontXml fnt in Fonts) {
      if (fnt.useCnt
          > 0 /* && fnt.newID<0*/) {
        fntNode.AppendChild(
            fnt.CreateXmlNode(_styleXml.CreateElement("font", ExcelPackage._schemaMain)));
        fnt.newID = count;
        count++;
      }
    }
    (fntNode as XmlElement).SetAttribute("count", count.ToString());

    //Fills
    count = 0;
    XmlNode fillsNode = _styleXml.SelectSingleNode(_fillsPath, _nameSpaceManager);
    fillsNode.RemoveAll();
    Fills[0].useCnt = 1; //Must exist (none);
    Fills[1].useCnt = 1; //Must exist (gray125);
    foreach (ExcelFillXml fill in Fills) {
      if (fill.useCnt > 0) {
        fillsNode.AppendChild(
            fill.CreateXmlNode(_styleXml.CreateElement("fill", ExcelPackage._schemaMain)));
        fill.newID = count;
        count++;
      }
    }

    (fillsNode as XmlElement).SetAttribute("count", count.ToString());

    //Borders
    count = 0;
    XmlNode bordersNode = _styleXml.SelectSingleNode(_bordersPath, _nameSpaceManager);
    bordersNode.RemoveAll();
    Borders[0].useCnt = 1; //Must exist blank;
    foreach (ExcelBorderXml border in Borders) {
      if (border.useCnt > 0) {
        bordersNode.AppendChild(
            border.CreateXmlNode(_styleXml.CreateElement("border", ExcelPackage._schemaMain)));
        border.newID = count;
        count++;
      }
    }
    (bordersNode as XmlElement).SetAttribute("count", count.ToString());

    XmlNode styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager);
    if (styleXfsNode == null && NamedStyles.Count > 0) {
      CreateNode(_cellStyleXfsPath);
      styleXfsNode = _styleXml.SelectSingleNode(_cellStyleXfsPath, _nameSpaceManager);
    }
    if (NamedStyles.Count > 0) {
      styleXfsNode.RemoveAll();
    }
    //NamedStyles
    count = normalIx > -1 ? 1 : 0; //If we have a normal style, we make sure it's added first.

    XmlNode cellStyleNode = _styleXml.SelectSingleNode(_cellStylesPath, _nameSpaceManager);
    if (cellStyleNode != null) {
      cellStyleNode.RemoveAll();
    }
    XmlNode cellXfsNode = _styleXml.SelectSingleNode(_cellXfsPath, _nameSpaceManager);
    cellXfsNode.RemoveAll();

    if (NamedStyles.Count > 0 && normalIx >= 0) {
      NamedStyles[normalIx].newID = 0;
      AddNamedStyle(0, styleXfsNode, cellXfsNode, NamedStyles[normalIx]);
    }
    foreach (ExcelNamedStyleXml style in NamedStyles) {
      if (!style.Name.Equals("normal", StringComparison.InvariantCultureIgnoreCase)) {
        AddNamedStyle(count++, styleXfsNode, cellXfsNode, style);
      } else {
        style.newID = 0;
      }
      cellStyleNode.AppendChild(
          style.CreateXmlNode(_styleXml.CreateElement("cellStyle", ExcelPackage._schemaMain)));
    }
    if (cellStyleNode != null) {
      (cellStyleNode as XmlElement).SetAttribute("count", count.ToString());
    }
    if (styleXfsNode != null) {
      (styleXfsNode as XmlElement).SetAttribute("count", count.ToString());
    }

    //CellStyle
    int xfix = 0;
    foreach (ExcelXfs xf in CellXfs) {
      if (xf.useCnt > 0 && !(normalIx >= 0 && NamedStyles[normalIx].XfId == xfix)) {
        cellXfsNode.AppendChild(
            xf.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain)));
        xf.newID = count;
        count++;
      }
      xfix++;
    }
    (cellXfsNode as XmlElement).SetAttribute("count", count.ToString());

    //Set dxf styling for conditional Formatting
    XmlNode dxfsNode = _styleXml.SelectSingleNode(_dxfsPath, _nameSpaceManager);
    foreach (var ws in _wb.Worksheets) {
      if (ws is ExcelChartsheet) {
        continue;
      }
      foreach (var cf in ws.ConditionalFormatting) {
        if (cf.Style.HasValue) {
          int ix = Dxfs.FindIndexById(cf.Style.Id);
          if (ix < 0) {
            ((ExcelConditionalFormattingRule)cf).DxfId = Dxfs.Count;
            Dxfs.Add(cf.Style.Id, cf.Style);
            var elem = ((XmlDocument)TopNode).CreateElement("d", "dxf", ExcelPackage._schemaMain);
            cf.Style.CreateNodes(new XmlHelperInstance(NameSpaceManager, elem), "");
            dxfsNode.AppendChild(elem);
          } else {
            ((ExcelConditionalFormattingRule)cf).DxfId = ix;
          }
        }
      }
    }
    if (dxfsNode != null) {
      (dxfsNode as XmlElement).SetAttribute("count", Dxfs.Count.ToString());
    }
  }

  private void AddNamedStyle(
      int id,
      XmlNode styleXfsNode,
      XmlNode cellXfsNode,
      ExcelNamedStyleXml style) {
    var styleXfs = CellStyleXfs[style.StyleXfId];
    styleXfsNode.AppendChild(
        styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain), true));
    styleXfs.newID = id;
    styleXfs.XfId = style.StyleXfId;

    var ix = CellXfs.FindIndexById(styleXfs.Id);
    if (ix < 0) {
      cellXfsNode.AppendChild(
          styleXfs.CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain)));
    } else {
      if (id < 0) {
        CellXfs[ix].XfId = id;
      }
      cellXfsNode.AppendChild(
          CellXfs[ix].CreateXmlNode(_styleXml.CreateElement("xf", ExcelPackage._schemaMain)));
      CellXfs[ix].useCnt = 0;
      CellXfs[ix].newID = id;
    }

    if (style.XfId >= 0) {
      style.XfId = CellXfs[style.XfId].newID;
    } else {
      style.XfId = 0;
    }
  }

  private void RemoveUnusedStyles() {
    CellXfs[0].useCnt = 1; //First item is allways used.
    foreach (ExcelWorksheet sheet in _wb.Worksheets) {
      var cse = new CellsStoreEnumerator<int>(sheet._styles);
      while (cse.Next()) {
        var v = cse.Value;
        if (v >= 0) {
          CellXfs[v].useCnt++;
        }
      }
    }
    foreach (ExcelNamedStyleXml ns in NamedStyles) {
      CellStyleXfs[ns.StyleXfId].useCnt++;
    }

    foreach (ExcelXfs xf in CellXfs) {
      if (xf.useCnt > 0) {
        if (xf.FontId >= 0) {
          Fonts[xf.FontId].useCnt++;
        }
        if (xf.FillId >= 0) {
          Fills[xf.FillId].useCnt++;
        }
        if (xf.BorderId >= 0) {
          Borders[xf.BorderId].useCnt++;
        }
      }
    }
    foreach (ExcelXfs xf in CellStyleXfs) {
      if (xf.useCnt > 0) {
        if (xf.FontId >= 0) {
          Fonts[xf.FontId].useCnt++;
        }
        if (xf.FillId >= 0) {
          Fills[xf.FillId].useCnt++;
        }
        if (xf.BorderId >= 0) {
          Borders[xf.BorderId].useCnt++;
        }
      }
    }
  }

  internal int GetStyleIdFromName(string name) {
    int i = NamedStyles.FindIndexById(name);
    if (i >= 0) {
      int id = NamedStyles[i].XfId;
      if (id < 0) {
        int styleXfId = NamedStyles[i].StyleXfId;
        ExcelXfs newStyle = CellStyleXfs[styleXfId].Copy();
        newStyle.XfId = styleXfId;
        id = CellXfs.FindIndexById(newStyle.Id);
        if (id < 0) {
          id = CellXfs.Add(newStyle.Id, newStyle);
        }
        NamedStyles[i].XfId = id;
      }
      return id;
    }
    return 0;
    //throw(new Exception("Named style does not exist"));
  }

  private string GetXmlNode(XmlNode node) {
    if (node == null) {
      return "";
    }
    if (node.Value != null) {
      return node.Value;
    }
    return "";
  }

  internal int CloneStyle(ExcelStyles style, int styleId) {
    return CloneStyle(style, styleId, false, false);
  }

  internal int CloneStyle(ExcelStyles style, int styleId, bool isNamedStyle) {
    return CloneStyle(style, styleId, isNamedStyle, false);
  }

  internal int CloneStyle(ExcelStyles style, int styleId, bool isNamedStyle, bool allwaysAdd) {
    ExcelXfs xfs;
    lock (style) {
      if (isNamedStyle) {
        xfs = style.CellStyleXfs[styleId];
      } else {
        xfs = style.CellXfs[styleId];
      }
      ExcelXfs newXfs = xfs.Copy(this);
      //Numberformat
      if (xfs.NumberFormatId > 0) {
        //rake36: Two problems here...
        //rake36:  1. the first time through when format stays equal to String.Empty, it adds a string.empty to the list of Number Formats
        //rake36:  2. when adding a second sheet, if the numberformatid == 164, it finds the 164 added by previous sheets but was using the array index
        //rake36:      for the numberformatid

        string format = string.Empty;
        foreach (var fmt in style.NumberFormats) {
          if (fmt.NumFmtId == xfs.NumberFormatId) {
            format = fmt.Format;
            break;
          }
        }
        //rake36: Don't add another format if it's blank
        if (!String.IsNullOrEmpty(format)) {
          int ix = NumberFormats.FindIndexById(format);
          if (ix < 0) {
            var item = new ExcelNumberFormatXml(NameSpaceManager) {
              Format = format,
              NumFmtId = NumberFormats.NextId++,
            };
            NumberFormats.Add(format, item);
            //rake36: Use the just added format id
            newXfs.NumberFormatId = item.NumFmtId;
          } else {
            //rake36: Use the format id defined by the index... not the index itself
            newXfs.NumberFormatId = NumberFormats[ix].NumFmtId;
          }
        }
      }

      //Font
      if (xfs.FontId > -1) {
        int ix = Fonts.FindIndexById(xfs.Font.Id);
        if (ix < 0) {
          ExcelFontXml item = style.Fonts[xfs.FontId].Copy();
          ix = Fonts.Add(xfs.Font.Id, item);
        }
        newXfs.FontId = ix;
      }

      //Border
      if (xfs.BorderId > -1) {
        int ix = Borders.FindIndexById(xfs.Border.Id);
        if (ix < 0) {
          ExcelBorderXml item = style.Borders[xfs.BorderId].Copy();
          ix = Borders.Add(xfs.Border.Id, item);
        }
        newXfs.BorderId = ix;
      }

      //Fill
      if (xfs.FillId > -1) {
        int ix = Fills.FindIndexById(xfs.Fill.Id);
        if (ix < 0) {
          var item = style.Fills[xfs.FillId].Copy();
          ix = Fills.Add(xfs.Fill.Id, item);
        }
        newXfs.FillId = ix;
      }

      //Named style reference
      if (xfs.XfId > 0) {
        var id = style.CellStyleXfs[xfs.XfId].Id;
        var newId = CellStyleXfs.FindIndexById(id);
        if (newId >= 0) {
          newXfs.XfId = newId;
        } else if (style._wb != _wb
            && allwaysAdd
                == false) //Not the same workbook, copy the namedstyle to the workbook or match the id
        {
          var nsFind = style.NamedStyles.ToDictionary(d => (d.StyleXfId));
          if (nsFind.ContainsKey(xfs.XfId)) {
            var st = nsFind[xfs.XfId];
            if (NamedStyles.ExistsKey(st.Name)) {
              newXfs.XfId = NamedStyles.FindIndexById(st.Name);
            } else {
              var ns = CreateNamedStyle(st.Name, st.Style);
              newXfs.XfId = NamedStyles.Count - 1;
            }
          }
        }
      }

      int index;
      if (isNamedStyle) {
        index = CellStyleXfs.Add(newXfs.Id, newXfs);
      } else {
        if (allwaysAdd) {
          index = CellXfs.Add(newXfs.Id, newXfs);
        } else {
          index = CellXfs.FindIndexById(newXfs.Id);
          if (index < 0) {
            index = CellXfs.Add(newXfs.Id, newXfs);
          }
        }
      }
      return index;
    }
  }
}
