/*******************************************************************************
 * 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.Collections.Immutable;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// Represents the different view states of the worksheet
/// </summary>
public class ExcelWorksheetView : XmlHelper {
  /// <summary>
  /// The worksheet panes after a freeze or split.
  /// </summary>
  public class ExcelWorksheetPanes : XmlHelper {
    private XmlElement _selectionNode;

    internal ExcelWorksheetPanes(XmlNamespaceManager ns, XmlNode topNode)
        : base(ns, topNode) {
      if (topNode.Name == "selection") {
        _selectionNode = topNode as XmlElement;
      }
    }

    private const string _activeCellPath = "@activeCell";

    /// <summary>
    /// Set the active cell. Must be set within the SelectedRange.
    /// </summary>
    public string ActiveCell {
      get {
        string address = GetXmlNodeString(_activeCellPath);
        if (address == "") {
          return "A1";
        }
        return address;
      }
      set {
        int toCol,
            toRow;
        if (_selectionNode == null) {
          CreateSelectionElement();
        }
        ExcelCellBase.GetRowColFromAddress(
            value,
            out var fromRow,
            out var fromCol,
            out toRow,
            out toCol);
        SetXmlNodeString(_activeCellPath, value);
        if (((XmlElement)TopNode).GetAttribute("sqref") == "") {
          SelectedRange = ExcelCellBase.GetAddress(fromRow, fromCol);
        }
        //TODO:Add fix for out of range here
      }
    }

    private void CreateSelectionElement() {
      _selectionNode = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      TopNode.AppendChild(_selectionNode);
      TopNode = _selectionNode;
    }

    private const string _selectionRangePath = "@sqref";

    /// <summary>
    /// Selected Cells.Used in combination with ActiveCell
    /// </summary>
    public string SelectedRange {
      get {
        string address = GetXmlNodeString(_selectionRangePath);
        if (address == "") {
          return "A1";
        }
        return address;
      }
      set {
        int toCol,
            toRow;
        if (_selectionNode == null) {
          CreateSelectionElement();
        }
        ExcelCellBase.GetRowColFromAddress(
            value,
            out var fromRow,
            out var fromCol,
            out toRow,
            out toCol);
        SetXmlNodeString(_selectionRangePath, value);
        if (((XmlElement)TopNode).GetAttribute("activeCell") == "") {
          ActiveCell = ExcelCellBase.GetAddress(fromRow, fromCol);
        }
        //TODO:Add fix for out of range here
      }
    }
  }

  private readonly ExcelWorksheet _worksheet;

  protected override ImmutableArray<string> SchemaNodeOrder { get; } = [
    "sheetViews",
    "sheetView",
    "pane",
    "selection",
  ];

  /// <summary>
  /// Creates a new ExcelWorksheetView which provides access to all the view states of the worksheet.
  /// </summary>
  /// <param name="ns"></param>
  /// <param name="node"></param>
  /// <param name="xlWorksheet"></param>
  internal ExcelWorksheetView(XmlNamespaceManager ns, XmlNode node, ExcelWorksheet xlWorksheet)
      : base(ns, node) {
    _worksheet = xlWorksheet;
    Panes = LoadPanes();
  }

  private ExcelWorksheetPanes[] LoadPanes() {
    XmlNodeList nodes = TopNode.SelectNodes("//d:selection", NameSpaceManager);
    if (nodes.Count == 0) {
      return [new ExcelWorksheetPanes(NameSpaceManager, TopNode)];
    }
    ExcelWorksheetPanes[] panes = new ExcelWorksheetPanes[nodes.Count];
    int i = 0;
    foreach (XmlElement elem in nodes) {
      panes[i++] = new(NameSpaceManager, elem);
    }
    return panes;
  }

  /// <summary>
  /// Returns a reference to the sheetView element
  /// </summary>
  protected internal XmlElement SheetViewElement => (XmlElement)TopNode;

  /// <summary>
  /// The active cell.
  /// </summary>
  public string ActiveCell {
    get => Panes[Panes.GetUpperBound(0)].ActiveCell;
    set => Panes[Panes.GetUpperBound(0)].ActiveCell = value;
  }

  /// <summary>
  /// Selected Cells in the worksheet.Used in combination with ActiveCell
  /// </summary>
  public string SelectedRange {
    get => Panes[Panes.GetUpperBound(0)].SelectedRange;
    set => Panes[Panes.GetUpperBound(0)].SelectedRange = value;
  }

  /// <summary>
  /// Indicates if the worksheet is selected within the workbook
  /// </summary>
  public bool TabSelected {
    get => GetXmlNodeBool("@tabSelected");
    set {
      if (value) {
        //    // ensure no other worksheet has its tabSelected attribute set to 1
        foreach (ExcelWorksheet sheet in _worksheet.Workbook.Worksheets) {
          sheet.View.TabSelected = false;
        }

        SheetViewElement.SetAttribute("tabSelected", "1");
        XmlElement bookView =
            _worksheet.Workbook.WorkbookXml.SelectSingleNode(
                "//d:workbookView",
                _worksheet.NameSpaceManager) as XmlElement;
        if (bookView != null) {
          bookView.SetAttribute("activeTab", (_worksheet.PositionID - 1).ToString());
        }
      } else {
        SetXmlNodeString("@tabSelected", "0");
      }
    }
  }

  /// <summary>
  /// Sets the view mode of the worksheet to pagelayout
  /// </summary>
  public bool PageLayoutView {
    get => GetXmlNodeString("@view") == "pageLayout";
    set {
      if (value) {
        SetXmlNodeString("@view", "pageLayout");
      } else {
        SheetViewElement.RemoveAttribute("view");
      }
    }
  }

  /// <summary>
  /// Sets the view mode of the worksheet to pagebreak
  /// </summary>
  public bool PageBreakView {
    get => GetXmlNodeString("@view") == "pageBreakPreview";
    set {
      if (value) {
        SetXmlNodeString("@view", "pageBreakPreview");
      } else {
        SheetViewElement.RemoveAttribute("view");
      }
    }
  }

  /// <summary>
  /// Show gridlines in the worksheet
  /// </summary>
  public bool ShowGridLines {
    get => GetXmlNodeBool("@showGridLines");
    set => SetXmlNodeString("@showGridLines", value ? "1" : "0");
  }

  /// <summary>
  /// Show the Column/Row headers (containg column letters and row numbers)
  /// </summary>
  public bool ShowHeaders {
    get => GetXmlNodeBool("@showRowColHeaders");
    set => SetXmlNodeString("@showRowColHeaders", value ? "1" : "0");
  }

  /// <summary>
  /// Window zoom magnification for current view representing percent values.
  /// </summary>
  public int ZoomScale {
    get => GetXmlNodeInt("@zoomScale");
    set {
      if (value < 10 || value > 400) {
        throw new ArgumentOutOfRangeException("Zoome scale out of range (10-400)");
      }
      SetXmlNodeString("@zoomScale", value.ToString());
    }
  }

  /// <summary>
  /// Flag indicating whether the sheet is in 'right to left' display mode. When in this mode,Column A is on the far right, Column B ;is one column left of Column A, and so on. Also,information in cells is displayed in the Right to Left format.
  /// </summary>
  public bool RightToLeft {
    get => GetXmlNodeBool("@rightToLeft");
    set => SetXmlNodeString("@rightToLeft", value ? "1" : "0");
  }

  internal bool WindowProtection {
    get => GetXmlNodeBool("@windowProtection", false);
    set => SetXmlNodeBool("@windowProtection", value, false);
  }

  /// <summary>
  /// Reference to the panes
  /// </summary>
  public ExcelWorksheetPanes[] Panes { get; internal set; }

  private readonly string _paneNodePath = "d:pane";
  private readonly string _selectionNodePath = "d:selection";

  /// <summary>
  /// Freeze the columns/rows to left and above the cell
  /// </summary>
  /// <param name="row"></param>
  /// <param name="column"></param>
  public void FreezePanes(int row, int column) {
    //TODO:fix this method to handle splits as well.
    if (row == 1 && column == 1) {
      UnFreezePanes();
    }
    string sqRef = SelectedRange,
        activeCell = ActiveCell;

    XmlElement paneNode = TopNode.SelectSingleNode(_paneNodePath, NameSpaceManager) as XmlElement;
    if (paneNode == null) {
      CreateNode(_paneNodePath);
      paneNode = TopNode.SelectSingleNode(_paneNodePath, NameSpaceManager) as XmlElement;
    }
    paneNode.RemoveAll(); //Clear all attributes
    if (column > 1) {
      paneNode.SetAttribute("xSplit", (column - 1).ToString());
    }
    if (row > 1) {
      paneNode.SetAttribute("ySplit", (row - 1).ToString());
    }
    paneNode.SetAttribute("topLeftCell", ExcelCellBase.GetAddress(row, column));
    paneNode.SetAttribute("state", "frozen");

    RemoveSelection();

    if (row > 1 && column == 1) {
      paneNode.SetAttribute("activePane", "bottomLeft");
      XmlElement sel = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      sel.SetAttribute("pane", "bottomLeft");
      if (activeCell != "") {
        sel.SetAttribute("activeCell", activeCell);
      }
      if (sqRef != "") {
        sel.SetAttribute("sqref", sqRef);
      }
      sel.SetAttribute("sqref", sqRef);
      TopNode.InsertAfter(sel, paneNode);
    } else if (column > 1 && row == 1) {
      paneNode.SetAttribute("activePane", "topRight");
      XmlElement sel = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      sel.SetAttribute("pane", "topRight");
      if (activeCell != "") {
        sel.SetAttribute("activeCell", activeCell);
      }
      if (sqRef != "") {
        sel.SetAttribute("sqref", sqRef);
      }
      TopNode.InsertAfter(sel, paneNode);
    } else {
      paneNode.SetAttribute("activePane", "bottomRight");
      XmlElement sel1 = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      sel1.SetAttribute("pane", "topRight");
      string cell = ExcelCellBase.GetAddress(1, column);
      sel1.SetAttribute("activeCell", cell);
      sel1.SetAttribute("sqref", cell);
      paneNode.ParentNode.InsertAfter(sel1, paneNode);

      XmlElement sel2 = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      cell = ExcelCellBase.GetAddress(row, 1);
      sel2.SetAttribute("pane", "bottomLeft");
      sel2.SetAttribute("activeCell", cell);
      sel2.SetAttribute("sqref", cell);
      sel1.ParentNode.InsertAfter(sel2, sel1);

      XmlElement sel3 = TopNode.OwnerDocument.CreateElement("selection", ExcelPackage._schemaMain);
      sel3.SetAttribute("pane", "bottomRight");
      if (activeCell != "") {
        sel3.SetAttribute("activeCell", activeCell);
      }
      if (sqRef != "") {
        sel3.SetAttribute("sqref", sqRef);
      }
      sel2.ParentNode.InsertAfter(sel3, sel2);
    }
    Panes = LoadPanes();
  }

  private void RemoveSelection() {
    //Find selection nodes and remove them
    XmlNodeList selections = TopNode.SelectNodes(_selectionNodePath, NameSpaceManager);
    foreach (XmlNode sel in selections) {
      sel.ParentNode.RemoveChild(sel);
    }
  }

  /// <summary>
  /// Unlock all rows and columns to scroll freely
  /// /// </summary>
  public void UnFreezePanes() {
    string sqRef = SelectedRange,
        activeCell = ActiveCell;

    XmlElement paneNode = TopNode.SelectSingleNode(_paneNodePath, NameSpaceManager) as XmlElement;
    if (paneNode != null) {
      paneNode.ParentNode.RemoveChild(paneNode);
    }
    RemoveSelection();

    Panes = LoadPanes();

    SelectedRange = sqRef;
    ActiveCell = activeCell;
  }
}
