/*******************************************************************************
 * 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-16
 *******************************************************************************/

using System;
using System.Globalization;
using System.Xml;

namespace OfficeOpenXml.Style.XmlAccess;

/// <summary>
/// Xml access class xfs records. This is the top level style object.
/// </summary>
public sealed class ExcelXfs : StyleXmlHelper {
  private readonly ExcelStyles _styles;

  internal ExcelXfs(XmlNamespaceManager nameSpaceManager, ExcelStyles styles)
      : base(nameSpaceManager) {
    _styles = styles;
    isBuildIn = false;
  }

  internal ExcelXfs(XmlNamespaceManager nsm, XmlNode topNode, ExcelStyles styles)
      : base(nsm, topNode) {
    _styles = styles;
    _xfID = GetXmlNodeInt("@xfId");
    if (_xfID == 0) {
      isBuildIn = true; //Normal taggen
    }
    _numFmtId = GetXmlNodeInt("@numFmtId");
    _fontId = GetXmlNodeInt("@fontId");
    _fillId = GetXmlNodeInt("@fillId");
    _borderId = GetXmlNodeInt("@borderId");
    _readingOrder = GetReadingOrder(GetXmlNodeString(_readingOrderPath));
    _indent = GetXmlNodeInt(_indentPath);
    _shrinkToFit = GetXmlNodeString(_shrinkToFitPath) == "1" ? true : false;
    _verticalAlignment = GetVerticalAlign(GetXmlNodeString(_verticalAlignPath));
    _horizontalAlignment = GetHorizontalAlign(GetXmlNodeString(_horizontalAlignPath));
    _wrapText = GetXmlNodeBool(_wrapTextPath);
    _textRotation = GetXmlNodeInt(textRotationPath);
    _hidden = GetXmlNodeBool(_hiddenPath);
    _locked = GetXmlNodeBool(_lockedPath, true);
  }

  private ExcelReadingOrder GetReadingOrder(string value) {
    switch (value) {
      case "1":
        return ExcelReadingOrder.LeftToRight;
      case "2":
        return ExcelReadingOrder.RightToLeft;
      default:
        return ExcelReadingOrder.ContextDependent;
    }
  }

  private ExcelHorizontalAlignment GetHorizontalAlign(string align) =>
    Enum.TryParse<ExcelHorizontalAlignment>(align, true, out var result)
        ? result
        : ExcelHorizontalAlignment.General;

  private ExcelVerticalAlignment GetVerticalAlign(string align) =>
    Enum.TryParse<ExcelVerticalAlignment>(align, true, out var result)
        ? result
        : ExcelVerticalAlignment.Bottom;

  private int _xfID;

  /// <summary>
  /// Style index
  /// </summary>
  public int XfId {
    get => _xfID;
    set => _xfID = value;
  }

  private int _numFmtId;

  internal int NumberFormatId {
    get => _numFmtId;
    set {
      _numFmtId = value;
      ApplyNumberFormat = (value > 0);
    }
  }

  private int _fontId;

  internal int FontId {
    get => _fontId;
    set => _fontId = value;
  }

  private int _fillId;

  internal int FillId {
    get => _fillId;
    set => _fillId = value;
  }

  private int _borderId;

  internal int BorderId {
    get => _borderId;
    set => _borderId = value;
  }

  private bool isBuildIn { get; set; }

  internal bool ApplyNumberFormat { get; set; }

  internal bool ApplyFont { get; set; }

  internal bool ApplyFill { get; set; }

  internal bool ApplyBorder { get; set; }

  internal bool ApplyAlignment { get; set; }

  internal bool ApplyProtection { get; set; }

  public ExcelStyles Styles { get; private set; }

  /// <summary>
  /// Numberformat properties
  /// </summary>
  public ExcelNumberFormatXml Numberformat => _styles.NumberFormats[_numFmtId < 0 ? 0 : _numFmtId];

  /// <summary>
  /// Font properties
  /// </summary>
  public ExcelFontXml Font => _styles.Fonts[_fontId < 0 ? 0 : _fontId];

  /// <summary>
  /// Fill properties
  /// </summary>
  public ExcelFillXml Fill => _styles.Fills[_fillId < 0 ? 0 : _fillId];

  /// <summary>
  /// Border style properties
  /// </summary>
  public ExcelBorderXml Border => _styles.Borders[_borderId < 0 ? 0 : _borderId];

  private const string _horizontalAlignPath = "d:alignment/@horizontal";
  private ExcelHorizontalAlignment _horizontalAlignment = ExcelHorizontalAlignment.General;

  /// <summary>
  /// Horizontal alignment
  /// </summary>
  public ExcelHorizontalAlignment HorizontalAlignment {
    get => _horizontalAlignment;
    set => _horizontalAlignment = value;
  }

  private const string _verticalAlignPath = "d:alignment/@vertical";
  private ExcelVerticalAlignment _verticalAlignment = ExcelVerticalAlignment.Bottom;

  /// <summary>
  /// Vertical alignment
  /// </summary>
  public ExcelVerticalAlignment VerticalAlignment {
    get => _verticalAlignment;
    set => _verticalAlignment = value;
  }

  private const string _wrapTextPath = "d:alignment/@wrapText";
  private bool _wrapText;

  /// <summary>
  /// Wraped text
  /// </summary>
  public bool WrapText {
    get => _wrapText;
    set => _wrapText = value;
  }

  private readonly string textRotationPath = "d:alignment/@textRotation";
  private int _textRotation;

  /// <summary>
  /// Text rotation angle
  /// </summary>
  public int TextRotation {
    get => (_textRotation == int.MinValue ? 0 : _textRotation);
    set => _textRotation = value;
  }

  private const string _lockedPath = "d:protection/@locked";
  private bool _locked = true;

  /// <summary>
  /// Locked when sheet is protected
  /// </summary>
  public bool Locked {
    get => _locked;
    set => _locked = value;
  }

  private const string _hiddenPath = "d:protection/@hidden";
  private bool _hidden;

  /// <summary>
  /// Hide formulas when sheet is protected
  /// </summary>
  public bool Hidden {
    get => _hidden;
    set => _hidden = value;
  }

  private const string _readingOrderPath = "d:alignment/@readingOrder";
  private ExcelReadingOrder _readingOrder = ExcelReadingOrder.ContextDependent;

  /// <summary>
  /// Readingorder
  /// </summary>
  public ExcelReadingOrder ReadingOrder {
    get => _readingOrder;
    set => _readingOrder = value;
  }

  private const string _shrinkToFitPath = "d:alignment/@shrinkToFit";
  private bool _shrinkToFit;

  /// <summary>
  /// Shrink to fit
  /// </summary>
  public bool ShrinkToFit {
    get => _shrinkToFit;
    set => _shrinkToFit = value;
  }

  private const string _indentPath = "d:alignment/@indent";
  private int _indent;

  /// <summary>
  /// Indentation
  /// </summary>
  public int Indent {
    get => (_indent == int.MinValue ? 0 : _indent);
    set => _indent = value;
  }

  internal void RegisterEvent(ExcelXfs xf) {
    //                RegisterEvent(xf, xf.Xf_ChangedEvent);
  }

  internal override string Id =>
    XfId
        + "|"
        + NumberFormatId
        + "|"
        + FontId
        + "|"
        + FillId
        + "|"
        + BorderId
        + VerticalAlignment
        + "|"
        + HorizontalAlignment
        + "|"
        + WrapText
        + "|"
        + ReadingOrder
        + "|"
        + isBuildIn
        + TextRotation
        + Locked
        + Hidden
        + ShrinkToFit
        + Indent;

  //return Numberformat.Id + "|" + Font.Id + "|" + Fill.Id + "|" + Border.Id + VerticalAlignment.ToString() + "|" + HorizontalAlignment.ToString() + "|" + WrapText.ToString() + "|" + ReadingOrder.ToString();
  internal ExcelXfs Copy() {
    return Copy(_styles);
  }

  internal ExcelXfs Copy(ExcelStyles styles) {
    ExcelXfs newXf = new ExcelXfs(NameSpaceManager, styles);
    newXf.NumberFormatId = _numFmtId;
    newXf.FontId = _fontId;
    newXf.FillId = _fillId;
    newXf.BorderId = _borderId;
    newXf.XfId = _xfID;
    newXf.ReadingOrder = _readingOrder;
    newXf.HorizontalAlignment = _horizontalAlignment;
    newXf.VerticalAlignment = _verticalAlignment;
    newXf.WrapText = _wrapText;
    newXf.ShrinkToFit = _shrinkToFit;
    newXf.Indent = _indent;
    newXf.TextRotation = _textRotation;
    newXf.Locked = _locked;
    newXf.Hidden = _hidden;
    return newXf;
  }

  internal override XmlNode CreateXmlNode(XmlNode topNode) {
    return CreateXmlNode(topNode, false);
  }

  internal XmlNode CreateXmlNode(XmlNode topNode, bool isCellStyleXsf) {
    TopNode = topNode;
    var doSetXfId =
        (!isCellStyleXsf
            && _xfID > int.MinValue
            && _styles.CellStyleXfs.Count > 0
            && _styles.CellStyleXfs[_xfID].newID > int.MinValue);
    if (_numFmtId > 0) {
      SetXmlNodeString("@numFmtId", _numFmtId.ToString());
      if (doSetXfId) {
        SetXmlNodeString("@applyNumberFormat", "1");
      }
    }
    if (_fontId >= 0) {
      SetXmlNodeString("@fontId", _styles.Fonts[_fontId].newID.ToString());
      if (doSetXfId) {
        SetXmlNodeString("@applyFont", "1");
      }
    }
    if (_fillId >= 0) {
      SetXmlNodeString("@fillId", _styles.Fills[_fillId].newID.ToString());
      if (doSetXfId) {
        SetXmlNodeString("@applyFill", "1");
      }
    }
    if (_borderId >= 0) {
      SetXmlNodeString("@borderId", _styles.Borders[_borderId].newID.ToString());
      if (doSetXfId) {
        SetXmlNodeString("@applyBorder", "1");
      }
    }
    if (_horizontalAlignment != ExcelHorizontalAlignment.General) {
      SetXmlNodeString(_horizontalAlignPath, SetAlignString(_horizontalAlignment));
    }
    if (doSetXfId) {
      SetXmlNodeString("@xfId", _styles.CellStyleXfs[_xfID].newID.ToString());
    }
    if (_verticalAlignment != ExcelVerticalAlignment.Bottom) {
      SetXmlNodeString(_verticalAlignPath, SetAlignString(_verticalAlignment));
    }
    if (_wrapText) {
      SetXmlNodeString(_wrapTextPath, "1");
    }
    if (_readingOrder != ExcelReadingOrder.ContextDependent) {
      SetXmlNodeString(_readingOrderPath, ((int)_readingOrder).ToString());
    }
    if (_shrinkToFit) {
      SetXmlNodeString(_shrinkToFitPath, "1");
    }
    if (_indent > 0) {
      SetXmlNodeString(_indentPath, _indent.ToString());
    }
    if (_textRotation > 0) {
      SetXmlNodeString(textRotationPath, _textRotation.ToString());
    }
    if (!_locked) {
      SetXmlNodeString(_lockedPath, "0");
    }
    if (_hidden) {
      SetXmlNodeString(_hiddenPath, "1");
    }
    return TopNode;
  }

  private string SetAlignString(Enum align) {
    string newName = Enum.GetName(align.GetType(), align);
    return newName.Substring(0, 1).ToLower(CultureInfo.InvariantCulture)
        + newName.Substring(1, newName.Length - 1);
  }
}
