using System;
using System.IO;
using Volpe.Cafe.Utils;
using Volpe.XlLib;
namespace Volpe.Cafe.IO
{
    [Serializable]
    public class Input
    {
        #region 
        public Input(string path) : this(path, null) { }
        public Input(string path, string password)
        {
            if (!File.Exists(path)) { throw new FileNotFoundException(ErrorStrings.XlOpenFileNotFound, path); }
            this.XlUtils    = new XlUtilities(path, true, password);
            this.SheetNames = this.XlUtils.GetWorksheetNames();
            this.ParseTitle();
        }
        #endregion
        #region 
        void ParseTitle()
        {
            string[] title = this.XlUtils.WorkbookTitle.Split(',');
            if (title != null)
            {
                if (title.Length >= 1) { this.Title   = title[0]; }
                if (title.Length >= 2) { this.Version = (float)Interaction.GetDouble(title[1]); }
            }
        }
        public void Close()
        {
            this.XlUtils.Close(false);
        }
        public void ActivateWorksheet(string name)
        {
            this.ActivateWorksheetInternal(name, XlCell.Empty, XlCell.Empty);
        }
        public void ActivateWorksheet(int index)
        {
            this.ActivateWorksheetInternal(index + 1, XlCell.Empty, XlCell.Empty);
        }
        public void ActivateWorksheet(string name, XlCell firstCell, XlCell lastCell)
        {
            this.ActivateWorksheetInternal(name, firstCell, lastCell);
        }
        public void ActivateWorksheet(int index, XlCell firstCell, XlCell lastCell)
        {
            this.ActivateWorksheetInternal(index + 1, firstCell, lastCell);
        }
        void ActivateWorksheetInternal(object index, XlCell firstCell, XlCell lastCell)
        {
            object[,] buf = this.XlUtils.GetData(index, firstCell, lastCell);
            this.Rows    = (buf == null) ? 0 : buf.GetUpperBound(0);
            this.Columns = (buf == null) ? 0 : buf.GetUpperBound(1);
            this.Buffer  = new object[this.Rows, this.Columns];
            for (int i = 0; i < this.Rows; i++)
            {
                for (int j = 0; j < this.Columns; j++)
                {
                    this.Buffer[i, j] = buf[i + 1, j + 1];
                }
            }
        }
        #region 
        public bool GetBool(int row, int column)
        {
            return Interaction.GetBool(this.Buffer[row, column]);
        }
        public int GetInt32(int row, int column)
        {
            return Interaction.GetInt32(this.Buffer[row, column]);
        }
        public double GetDouble(int row, int column)
        {
            return Interaction.GetDouble(this.Buffer[row, column]);
        }
        public char GetChar(int row, int column)
        {
            return Interaction.GetChar(this.Buffer[row, column]);
        }
        public string GetString(int row, int column)
        {
            return Interaction.GetString(this.Buffer[row, column]);
        }
        #endregion
        public void GetMinMaxYears(int row, int startColumn, out int minYear, out int maxYear)
        {
            minYear = 0;
            maxYear = 0;
            if (row == -1)
            {
                throw new ArgumentException("The value of row must be greater than or equal to 0.", "row");
            }
            else if (startColumn == -1)
            {   
                return;
            }
            int cols = this.Columns;
            int numYears = 0;
            minYear = this.GetInt32(row, startColumn);
            if (minYear == 0)
            {   
                minYear = Interaction.GetInt32(this.GetString(row, startColumn).Replace("MY", ""));
            }
            if (minYear < ModelYear.MinYear)
            {
                throw new InputException(this.XlUtils.Path, "Only model years " + ModelYear.MinYear + " and above are supported.");
            }
            int prev = minYear - 1, current = minYear;
            while (prev + 1 == current)
            {
                numYears++;
                prev = current;
                if (startColumn + numYears >= cols)
                {   
                    break;
                }
                current = this.GetInt32(row, startColumn + numYears);
                if (current == 0)
                {
                    current = Interaction.GetInt32(this.GetString(row, startColumn + numYears).Replace("MY", ""));
                }
            }
            maxYear = prev;
        }
        #endregion
        #region 
        public XlUtilities XlUtils { get; private set; }
        public string Title { get; private set; }
        public float Version { get; private set; }
        public string[] SheetNames { get; private set; }
        public object[,] Buffer { get; private set; }
        public int Rows { get; private set; }
        public int Columns { get; private set; }
        #endregion
    }
}

