using System;
using System.Collections.Generic;

namespace WindStressPRM
{
    /// <summary>
    /// Generic Matrix of type T
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Matrix<T>
    {   
        /// <summary>
        /// origin coordinates of matrix. This must be top left corner
        /// </summary>
        public Coordinate Origin { get; set; }
        /// <summary>
        /// get coordinate of cell at index
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Coordinate CellToProjection(Index index) {
            return new Coordinate(Origin.X + index.Row*Size.Width, Origin.Y - index.Col*Size.Height);
        }
        /// <summary>
        /// get index of cell for coordinate
        /// </summary>
        /// <param name="coordinate"></param>
        /// <returns></returns>
        public Index ProjectionToCell(Coordinate coordinate)
        {
            double rwDiff = (coordinate.X - Origin.X) / Size.Width;
            double colDiff = (coordinate.Y - Origin.Y) / -Size.Height;
            int iRow = (int)Math.Round(rwDiff);
            int iCol = (int)Math.Round(colDiff);

            if (iRow < 0 || iCol < 0 || iRow >= RowsCount() || iCol >= ColumnCount())
            {
                throw new Exception("projectionToCell method trying to find uncorrect index");
            }
            return new Index(iRow, iCol);            
        }
        /// <summary>
        /// Size of cell. In meters
        /// </summary>
        public CellSize Size { get; set; }
        /// <summary>
        /// Cells Container
        /// </summary>
        public T[,] Cells { get; set; }
        /// <summary>
        /// Number of rows in matrix
        /// </summary>
        /// <returns></returns>
        public int RowsCount()
        {
            return Cells.Rank > 0 ? Cells.GetLength(0) : 0;
        }
        /// <summary>
        /// Number of columns 
        /// </summary>
        /// <returns></returns>
        public int ColumnCount()
        {
            return Cells.Rank > 1 ? Cells.GetLength(1) : 0;
        }
    }
}