using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;

using STC;
using Spherical;
using Spherical.IO;
using Spherical.Visualizer;

namespace VoServices.Footprint.Web
{
    public partial class operation : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Title = "Footprint Services";
        }
        protected void btnTest1_Click(object sender, EventArgs e)
        {
            tblResult.Visible = false;
            tbLeft.Text = "REGION CONVEX 0.9 0.2 0 0.99";
            tbRight.Text = "REGION CONVEX 1 0 0 0.98";
        }
        protected void btnTest2_Click(object sender, EventArgs e)
        {
            tblResult.Visible = false;
            MemoryStream mem = new MemoryStream
                (Resources.Resource.fieldlist_misgr1_select, false);
            BinReader rdr = new BinReader(mem);
            Region r = rdr.ReadRegion();
            rdr.Close();
            STCRegion rt = STC.Adapter.StcFromRegion(r);
            tbLeft.Text = STC.Adapter.ToXml(rt);

            double ra = 347, dec = 0;
            double ee = 0.75;
            List<Cartesian> pts = new List<Cartesian>(4);
            pts.Add(new Cartesian(ra + ee, dec + ee));
            pts.Add(new Cartesian(ra + ee, dec - ee));
            pts.Add(new Cartesian(ra - ee, dec - ee));
            pts.Add(new Cartesian(ra - ee, dec + ee));
            Convex k = new Convex(pts, PointOrder.Safe);
            Region c = new Region(k, false);
            tbRight.Text = c.ToString();
        }
        protected void btnTest3_Click(object sender, EventArgs e)
        {
            tblResult.Visible = false;
            MemoryStream mem = new MemoryStream
                (Resources.Resource.fieldlist_misgr1, false);
            BinReader rdr = new BinReader(mem);
            Region r = rdr.ReadRegion();
            rdr.Close();
            STCRegion rt = STC.Adapter.StcFromRegion(r);
            tbLeft.Text = STC.Adapter.ToXml(rt);
            tbRight.Text = Samples.dr4repr;
        }
        protected void btnTest4_Click(object sender, EventArgs e)
        {
            tblResult.Visible = false;
            MemoryStream mem;
            BinReader rdr;

            mem = new MemoryStream(Resources.Resource.wfpc2M101e, false);
            rdr = new BinReader(mem);
            Region r = rdr.ReadRegion();
            rdr.Close();
            STCRegion rt = STC.Adapter.StcFromRegion(r);

            mem = new MemoryStream(Resources.Resource.AcsWfcM101e, false);
            rdr = new BinReader(mem);
            Region l = rdr.ReadRegion();
            rdr.Close();
            STCRegion lt = STC.Adapter.StcFromRegion(l);

            tbLeft.Text = STC.Adapter.ToXml(lt);
            tbRight.Text = STC.Adapter.ToXml(rt);
        }
        protected void btnClear_Click(object sender, EventArgs e)
        {
            this.tblResult.Visible = false;
            tbLeft.Text = "";
            tbRight.Text = "";
            lblLeft.ForeColor = System.Drawing.Color.Black;
            lblRight.ForeColor = System.Drawing.Color.Black;
        }

        protected void btnIsect_Click(object sender, EventArgs e)
        {
            #region Parse textboxes ...

            string txt1 = tbLeft.Text.Trim();
            string txt2 = tbRight.Text.Trim();
            Region r1, r2;
            try
            {
                r1 = Region.Parse(txt1, true);
            }
            catch (ArgumentException ex)
            {
                try
                {
                    STCRegion rt = STC.Adapter.XmlToStcRegion(txt1);
                    r1 = STC.Adapter.ToRegion(rt);
                }
                catch
                {
                    lblLeft.ForeColor = System.Drawing.Color.Red;
                    return;
                }
            }
            try
            {
                r2 = Region.Parse(txt2, true);
            }
            catch (ArgumentException ex)
            {
                try
                {
                    STCRegion rt = STC.Adapter.XmlToStcRegion(txt2);
                    r2 = STC.Adapter.ToRegion(rt);
                }
                catch
                {
                    lblRight.ForeColor = System.Drawing.Color.Red;
                    return;
                }
            }

            #endregion
            #region Simplify region and perform operation ...

            // do the work
            r1.Simplify(false);
            r2.Simplify(false);
            Region rI = r1.Intersect(r2);
            rI.Simplify();

            this.tbBottom.Text = STC.Adapter.ToXml(STC.Adapter.StcFromRegion(rI));
            double area = rI.Area.Value;

            #endregion
            #region Find center and scaling for plot ...

            // find center
            List<Cartesian> plist = new List<Cartesian>();
            foreach (Convex c in rI.ConvexList)
                foreach (Patch p in c.PatchList)
                    plist.Add(p.Mec.Vector);
            Cartesian center = Cartesian.CenterOfMass(plist, true);

            // punch hole and simplify for plotting
            Halfspace valid = new Halfspace(center, -0.99);
            rI.Intersect(valid);
            r1.Intersect(valid);
            r2.Intersect(valid);
            rI.Simplify();
            r1.Simplify();
            r2.Simplify();

            // radius
            double max_radius = 0;
            foreach (Convex c in rI.ConvexList)
            {
                foreach (Patch p in c.PatchList)
                {
                    double radius = center.AngleInRadian(p.Mec.Vector) 
                        + p.Mec.RadiusInRadian;
                    if (radius > max_radius) max_radius = radius;
                }
            }
            max_radius *= 1.2; // + 20% 
            if (max_radius >= Math.PI) max_radius = Math.PI - double.Epsilon;

            double scale = 2 * max_radius * Const.Radian2Degree * 3600 / 512;
            //double scale = 4*Math.Tan(max_radius/2) * Const.Radian2Degree * 3600 / 512;

            #endregion
            #region Plotting ...

            Spherical.Visualizer.LcdColor lcd = new Spherical.Visualizer.LcdColor();
            Spherical.Visualizer.RegionCanvas canvas = new Spherical.Visualizer.RegionCanvas
                (center.RA, center.Dec, "STR", 768, 512, 3600 / scale, false);
            canvas.DrawRegion(r1, lcd["g"], 1);
            canvas.DrawRegion(r2, lcd["l"], 1);
            canvas.DrawRegion(rI, lcd["r"], 1);
            canvas.drawLabel(String.Format("Center (RA, Dec): {0:n}, {1:n} deg.", center.RA, center.Dec));
            canvas.drawLabel(String.Format("Area: {0:g} sq.deg.", area));

            try { canvas.drawGrid(); }
            catch { };

            MemoryStream mem = new MemoryStream();
            canvas.Image.Save(mem, System.Drawing.Imaging.ImageFormat.Gif);
            Session["gifbytes"] = mem.ToArray();

            #endregion
            #region Set page properties and output result ...

            // set page properties
            this.tblResult.Visible = true;
            this.imgPlot.Visible = true;
            this.lblLeft.ForeColor = System.Drawing.Color.Black;
            this.lblRight.ForeColor = System.Drawing.Color.Black;

            #endregion
        }

        protected void btnUnion_Click(object sender, EventArgs e)
        {
            #region Parse textboxes ...

            string txt1 = tbLeft.Text.Trim();
            string txt2 = tbRight.Text.Trim();
            Region r, r1, r2;
            try
            {
                r1 = Region.Parse(txt1, true);
            }
            catch (ArgumentException ex)
            {
                try
                {
                    STCRegion rt = STC.Adapter.XmlToStcRegion(txt1);
                    r1 = STC.Adapter.ToRegion(rt);
                }
                catch
                {
                    lblLeft.ForeColor = System.Drawing.Color.Red;
                    return;
                }
            }
            try
            {
                r2 = Region.Parse(txt2, true);
            }
            catch (ArgumentException ex)
            {
                try
                {
                    STCRegion rt = STC.Adapter.XmlToStcRegion(txt2);
                    r2 = STC.Adapter.ToRegion(rt);
                }
                catch
                {
                    lblRight.ForeColor = System.Drawing.Color.Red;
                    return;
                }
            }

            #endregion
            #region Simplify region and perform operation ...

            r1.Simplify();
            r2.Simplify();

            r = r1;
            r.Union(r2);
            r.Simplify();

            this.tbBottom.Text = STC.Adapter.ToXml(STC.Adapter.StcFromRegion(r));
            double area = r.Area.Value;

            #endregion
            #region Find center and scaling for plot ...

            // find center
            List<Cartesian> plist = new List<Cartesian>();
            foreach (Convex c in r.ConvexList)
                foreach (Patch p in c.PatchList)
                    plist.Add(p.Mec.Vector);
            Cartesian center = Cartesian.CenterOfMass(plist, true);

            // simplify for plotting
            r.Intersect(new Halfspace(center, -0.99));
            r.Simplify();

            // radius
            double max_radius = 0;
            foreach (Convex c in r.ConvexList)
            {
                foreach (Patch p in c.PatchList)
                {
                    double radius = center.AngleInRadian(p.Mec.Vector) + p.Mec.RadiusInRadian;
                    if (radius > max_radius) max_radius = radius;
                }
            }
            max_radius *= 1.1; // + 10% 
            if (max_radius >= Math.PI) max_radius = Math.PI - double.Epsilon;

            double scale = 2 * max_radius * Const.Radian2Degree * 3600 / 512;
            //double scale = 4*Math.Tan(max_radius/2) * Const.Radian2Degree * 3600 / 512;

            #endregion
            #region Plotting ...

            Spherical.Visualizer.LcdColor lcd = new Spherical.Visualizer.LcdColor();
            Spherical.Visualizer.RegionCanvas canvas = new Spherical.Visualizer.RegionCanvas
                (center.RA, center.Dec, "STR", 768, 512, 3600 / scale, false);
            //canvas.drawLabel(String.Format("Nc: {0}", r.ConvexList.Count));
            canvas.DrawRegion(r, lcd["y"], 1);
            canvas.drawLabel(String.Format("Center (RA, Dec): {0:n}, {1:n} deg.", 
                center.RA, center.Dec));
            canvas.drawLabel(String.Format("Area: {0:g} sq.deg.", area));
            try { canvas.drawGrid(); } catch { };

            MemoryStream mem = new MemoryStream();
            canvas.Image.Save(mem, System.Drawing.Imaging.ImageFormat.Gif);
            Session["gifbytes"] = mem.ToArray();

            #endregion
            #region Set page properties and output result ...

            this.tblResult.Visible = true;
            this.lblLeft.ForeColor = System.Drawing.Color.Black;
            this.lblRight.ForeColor = System.Drawing.Color.Black;

            #endregion
        }

    }
}