using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace nft.framework.drawing {
    /// <summary>
    /// Projective shape of cells rectangle on screen.\n
    /// The origin (X,Y) is the most lower vertex on screen, by pixel.
    /// The L(eft),R(ight)Width and Height have positive value for upper direction, by pixel.
    /// </summary>
    public class QuaterViewRect {
        /// X location of most lower vertex on screen, by pixel.
        public int X;
        /// Y location of most lower vertex on screen, by pixel.
        public int Y;
        /// Left side width by pixel, positive value for upper-left direction. odd value is not recommended.
        public int LWidth;
        /// Right side width by pixel, positive value for upper-right direction. odd value is not recommended.
        public int RWidth;
        /// Height of vertical part by cell counts, positive value for upper direction.
        public int Height;

        public QuaterViewRect(int x, int y, int lWidth, int rWidth, int height) {
            this.X = x;
            this.Y = y;
            this.LWidth = Math.Max(0, lWidth);
            this.RWidth = Math.Max(0, rWidth);
            this.Height = height;
        }

        public QuaterViewRect(int x, int y, int lWidth, int rWidth)
            : this(x, y, lWidth, rWidth, 0) {

        }

        public QuaterViewRect(int x, int y)
            : this(x, y, 0, 0, 0) {

        }


        public QuaterViewRect(Point pt, int lWidth, int rWidth, int height) {
            this.X = pt.X;
            this.Y = pt.Y;
            this.LWidth = Math.Max(0, lWidth);
            this.RWidth = Math.Max(0, rWidth);
            this.Height = height;
        }

        public QuaterViewRect(Point pt, int lWidth, int rWidth)
            : this(pt, lWidth, rWidth, 0) {

        }

        public QuaterViewRect(Point pt)
            : this(pt, 0, 0, 0) {

        }

        public Point TextureOffset {
            get {
                Point pt = new Point(-LWidth, -(Height + (LWidth + RWidth) / 2));
                return pt;
            }
        }

        /// <summary>
        /// Returns bounding rect.
        /// </summary>
        public Rectangle GetBounds() {
            int w = this.LWidth + this.RWidth;
            int h = this.Height + w / 2;
            return new Rectangle(this.X - this.LWidth, this.Y - h, w, h);
        }

        /// <summary>
        /// Retruns 6 vertices of hexagonal shape.
        /// </summary>
        /// <returns></returns>
        public Point[] GetVertices() {
            Point[] arr = new Point[6];
            for (int i = 0; i < 6; i++) {
                arr[i] = new Point();
            }
            GetVertices(ref arr);
            return arr;
        }

        /// <summary>
        /// Set 6 vertices of hexagonal shape into the array.
        /// </summary>
        /// <param name="pt">Must set instance of Point for each element of the array before call.</param>
        /// <param name="rect"></param>
        public void GetVertices(ref Point[] pt) {
            int l2 = this.LWidth / 2;
            int r2 = this.RWidth / 2;
            int w = this.LWidth + this.RWidth;
            int x1 = this.X - this.LWidth;
            int x2 = x1 + w;
            int y2 = this.Y - this.Height - w/2;
            pt[0].X = this.X; pt[0].Y = this.Y;
            pt[1].X = x1; pt[1].Y = this.Y - l2;
            pt[2].X = x1; pt[2].Y = y2 + r2;
            pt[3].X = x1 + this.RWidth; pt[3].Y = y2;
            pt[4].X = x2; pt[4].Y = y2 + l2;
            pt[5].X = x2; pt[5].Y = this.Y - r2;
        }
    }
}
