using System;
using System.Drawing;
using nft.core.geometry;
using nft.framework;
using nft.util;

namespace nft.core.structure
{
	public interface ISiteDefiner{
        Rectangle GetTextureRect(ParamsReader reader);
        ISiteDefiner GetRotated(InterCardinalDirection view_upper);
    }

	[Serializable]
    public class BasicSiteDefiner : ISiteDefiner
	{
        static protected readonly string ORG_TOPLEFT = "top_left";
        static protected readonly string ORG_BOTTOMLEFT = "bottom_left";
        static protected readonly string ORG_VTX_LOWERLEFT = "vertex_lower_left";
        static protected readonly string ORG_VTX_LOWEST = "vertex_lowest";

        private Size3D size;
        private InterCardinalDirection upper_dir;
        public BasicSiteDefiner(ParamsReader reader) {
            Init(reader);
        }

        protected BasicSiteDefiner(Size3D sz) {
            size = sz;
        }

        protected void Init(ParamsReader reader) {
            Size sz = StringParseUtil.CreateSize(reader["size"].InnerText);
            int height = int.Parse(reader["height"].InnerText);
            upper_dir = (InterCardinalDirection)Direction.Parse(reader["upper-direction"].InnerText).index;
            size = new Size3D(sz, height);
        }

        public Rect3D Bounds {
            get {
                return new Rect3D(new Location(), size);
            }
        }

        public Rectangle GetTextureRect(ParamsReader reader) {
            Size sz = size.ProjectionSize;
            ParamsReader orgin = reader["origin"];
            Point pt = StringParseUtil.CreatePoint(orgin.InnerText);
            String _as = orgin["as"].InnerTextOr(ORG_TOPLEFT);
            if (ORG_TOPLEFT.Equals(_as)) {
                // do nothing
            } else if (ORG_VTX_LOWEST.Equals(_as)) {
                pt.Y -= sz.Height;
                pt.X += size.sx;
            } else if (ORG_BOTTOMLEFT.Equals(_as)) {
                pt.Y -= sz.Height;
            } else if (ORG_VTX_LOWEST.Equals(_as)) {
                pt.Y -= (size.sz + size.sy / 2);
            }
            return new Rectangle(pt, sz);
        }

        public ISiteDefiner GetRotated(InterCardinalDirection view_upper) {
            if (Direction.IsPerpendiculer(upper_dir, view_upper)) {
                return new BasicSiteDefiner(new Size3D(size.sy, size.sx, size.sz));
            } else {
                return new BasicSiteDefiner(size);
            }
        }
    }
}
