using System.Collections.Generic;
using System.Diagnostics;

namespace LibWorkbooks.Model
{
    public class RangeRef
    {
        public RangeRef(CellRef start, CellRef end)
        {
            Start = start;
            End = end;
        }

        public RangeRef(CellRef start, int endColumn, int endRow)
            : this(start, new CellRef(start.SheetName, (endColumn, endRow)))
        { }

        public RangeRef Offset(int columnOffset, int rowOffset)
        {
            var start = Start.Offset(columnOffset, rowOffset);
            var end = End.Offset(columnOffset, rowOffset);
            return new RangeRef(start, end);
        }

        public CellRef Start { get; }
        
        public CellRef End { get; }

        public override string ToString()
        {
            return string.Format("'{0}'!{1}:{2}",
                Start.SheetName,
                CellRef.ConvertCoordToAddress((Start.Column, Start.Row)),
                CellRef.ConvertCoordToAddress((End.Column, End.Row)));
        }

        public bool IsVector()
        {
            return IsSingleRow() || IsSingleColumn();
        }

        internal List<CellRef> GetVector()
        {
            Debug.Assert(IsVector());

            var result = new List<CellRef>();

            if (IsSingleColumn())
            {
                var col = Start.Column;
                var sheetName = Start.SheetName;
                var numRows = NumRows();
                var lastRow = Start.Row + numRows - 1;
                for (var row = Start.Row; row <= lastRow; row++)
                {
                    result.Add(new CellRef(sheetName, (col, row)));
                }
            }
            else
            {
                Debug.Assert(IsSingleRow());

                var row = Start.Row;
                var sheetName = Start.SheetName;
                var numCols = NumCols();
                var lastCol = Start.Column + numCols - 1;
                for (var col = Start.Column; col <= lastCol; col++)
                {
                    result.Add(new CellRef(sheetName, (col, row)));
                }
            }

            return result;
        }

        public bool IsSingleColumn()
        {
            Debug.Assert(Start.SheetName == End.SheetName);
            return Start.Column == End.Column;
        }

        public bool IsSingleRow()
        {
            Debug.Assert(Start.SheetName == End.SheetName);
            return Start.Row == End.Row;
        }

        public int NumRows()
        {
            Debug.Assert(Start.SheetName == End.SheetName);
            return End.Row - Start.Row + 1;
        }

        public int NumCols()
        {
            Debug.Assert(Start.SheetName == End.SheetName);
            return End.Column - Start.Column + 1;
        }
    }
}