using System;

using OpenNETCF.Web.UI;

using OpenNETCF.Web.Html;

using OpenNETCF.Web.Html.Meta;

using OpenNETCF.Peripherals;

using System.Drawing;

using System.IO;

using System.Net;

using System.Xml;

using System.Reflection;

 

namespace SampleSite

{

    public class CameraDemo : Page

    {

        private const string TEMP_STORAGE_FOLDER = "temp";

        private const string TEMP_FILE_NAME = "camera.png";

        private const string CONFIG_FILE_NAME = "CameraConfig.xml";

        private const string CLASS_NAME = "CAMERA_DEMO";

 

        private static string m_cameraType;

        private static string m_cameraIP;

        private static string m_cameraUID;

        private static string m_cameraPWD;

        private static bool m_cameraExists = false;

 

        internal static ICamera Camera;

 

        private static string m_cameraError = "No camera has been cofigured for this server";

       

        static CameraDemo()

        {

            // we'll assume that if a camera config file exists, then the camera exists

            string folder = Path.Combine(OpenNETCF.Web.Server.WebServer.PhysicalPath, "bin");

            string filename = Path.Combine(folder, CONFIG_FILE_NAME);

 

            if (File.Exists(filename))

            {

                try

                {

                    XmlDocument doc = new XmlDocument();

                    doc.Load(filename);

                   

                    XmlNode node = doc.FirstChild.NextSibling;

 

                    if (string.Compare(node.Name, "camera") == 0)

                    {

                        XmlAttribute attrib = node.Attributes["ip"];

                        if (attrib == null) return;

                        m_cameraIP = attrib.Value;

 

                        attrib = node.Attributes["uid"];

                        m_cameraUID = (attrib == null) ? null : attrib.Value;

 

                        attrib = node.Attributes["pwd"];

                        m_cameraPWD = (attrib == null) ? null : attrib.Value;

 

                        attrib = node.Attributes["type"];

                        if (attrib == null) return;

                        m_cameraType = attrib.Value;

 

                        m_cameraExists = true;

                    }

                }

                catch

                {

                    // if we have a failure, we simply don't config the camera

                }

            }

 

        }

 

        protected override void Page_Load(object sender, EventArgs e)

        {

            int et = Environment.TickCount;

 

            // create a document

            Document doc = new Document();

 

            // add a doc header

            DocumentHead head = new DocumentHead("Padarn Camera Demo", new StyleInfo("css/SampleSite.css"));

            doc.Head = head;

 

            // tell the client browser not to cache

            Response.Cache.SetNoStore();

 

            Utility.AddPadarnHeaderToDocument(doc, true, "CameraDemo");

 

            Div cameraIP = new Div();

            cameraIP.Add(new RawText(string.Format("Camera is at address: {0}", m_cameraIP)));

            doc.Body.Add(cameraIP);

 

            // create the camera control

            Assembly asm = Assembly.Load("OpenNETCF.Peripherals.Camera");

            Camera = (ICamera)asm.CreateInstance("OpenNETCF.Peripherals.Camera.DCS900");

            Camera.Initialize(IPAddress.Parse(m_cameraIP), m_cameraUID, m_cameraPWD);

 

            if (Camera.SupportsPanTilt)

            {

                ShowPanAndTiltPage(doc);

            }

            else

            {

                ShowStationaryPage(doc);

            }

 

            #region --- load time ---

            et = Environment.TickCount - et;

 

            Paragraph loadTimeParagraph = new Paragraph(string.Format("Page loaded in {0:0.000} sec", (float)((float)et / 1000f)));

 

            // some elements allow setting element-specific styles

            loadTimeParagraph.Styles.Add(new ElementStyle("font-size", "10px"));

            loadTimeParagraph.Styles.Add(new ElementStyle("text-align", "left"));

            doc.Body.Elements.Add(loadTimeParagraph);

            #endregion

 

            Response.Write(doc.OuterHtml);

            Response.Flush();

        }

 

        private void ShowPanAndTiltPage(Document doc)

        {

            string folder = Path.Combine(OpenNETCF.Web.Server.WebServer.PhysicalPath, TEMP_STORAGE_FOLDER);

            string filename = Path.Combine(TEMP_STORAGE_FOLDER, TEMP_FILE_NAME);

 

            #region --- camera control box ---

            // create the camera control buttons

            Div controlDiv = new Div("controls", CLASS_NAME);

            Table controlTable = new Table(CLASS_NAME, null, Align.Center);

 

            // note that all of the FORMs are necessary for IE (tested on IE7). 

            // Firefox correctly handles multiple submits with the same name, but IE doesn't

            Row row = new Row();

            row.Cells.Add(new Cell(SpecialCharacters.Space));

            Form form = new Form("CameraDemo.aspx", FormMethod.Get);

            form.Elements.Add(new Button(new ButtonInfo(ButtonType.Submit, "UP", "CONTROL", "UP", null)));

            row.Cells.Add(new Cell(form));

            row.Cells.Add(new Cell(SpecialCharacters.Space));

            controlTable.Rows.Add(row);

 

            row = new Row();

            form = new Form("CameraDemo.aspx", FormMethod.Get);

            form.Elements.Add(new Button(new ButtonInfo(ButtonType.Submit, "LEFT", "CONTROL", "LEFT", null)));

            row.Cells.Add(new Cell(form));

            form = new Form("CameraDemo.aspx", FormMethod.Get);

            form.Elements.Add(new Button(new ButtonInfo(ButtonType.Submit, "CAPTURE", "CONTROL", "CAPTURE", null)));

            row.Cells.Add(new Cell(form));

            form = new Form("CameraDemo.aspx", FormMethod.Get);

            form.Elements.Add(new Button(new ButtonInfo(ButtonType.Submit, "RIGHT", "CONTROL", "RIGHT", null)));

            row.Cells.Add(new Cell(form));

            controlTable.Rows.Add(row);

 

            row = new Row();

            row.Cells.Add(new Cell(SpecialCharacters.Space));

            form = new Form("CameraDemo.aspx", FormMethod.Get);

            form.Elements.Add(new Button(new ButtonInfo(ButtonType.Submit, "DOWN", "CONTROL", "DOWN", null)));

            row.Cells.Add(new Cell(form));

            row.Cells.Add(new Cell(SpecialCharacters.Space));

            controlTable.Rows.Add(row);

 

            controlDiv.Elements.Add(controlTable);

            doc.Body.Elements.Add(controlDiv);

 

            #endregion

 

            #region --- camera capture ---

            // only capture if we have a configured camera

            if (m_cameraExists)

            {

//                MegaTecCamera camera = new MegaTecCamera(IPAddress.Parse(m_cameraIP), m_cameraUID, m_cameraPWD);

 

                string control = Request.QueryString["Control"] as string;

                if (control == null) control = string.Empty;

 

                // move camera if requested

                switch (control.ToLower())

                {

                    // the camera is set up physically with the L&R swapped, so invert them here

                    case "left":

                        Camera.Pan(OpenNETCF.Peripherals.Camera.PanDirection.Right);

                        // give the camera time to move before taking another shot

                        System.Threading.Thread.Sleep(500);

                        break;

                    case "right":

                        Camera.Pan(OpenNETCF.Peripherals.Camera.PanDirection.Left);

                        // give the camera time to move before taking another shot

                        System.Threading.Thread.Sleep(500);

                        break;

                    case "up":

                        Camera.Tilt(OpenNETCF.Peripherals.Camera.TiltDirection.Up);

                        // give the camera time to move before taking another shot

                        System.Threading.Thread.Sleep(500);

                        break;

                    case "down":

                        Camera.Tilt(OpenNETCF.Peripherals.Camera.TiltDirection.Down);

                        // give the camera time to move before taking another shot

                        System.Threading.Thread.Sleep(500);

                        break;

                }

 

                Bitmap img = null;

 

                // make sure our destination folder exists

                if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);

 

                // loop because sometimes the web server on the camera returns nothing

                do

                {

                    try

                    {

                        using (img = Camera.GetImage() as Bitmap)

                        {

                            if (img != null)

                            {

                                img.Save(Path.Combine(folder, TEMP_FILE_NAME), System.Drawing.Imaging.ImageFormat.Png);

                            }

                        }

                    }

                    catch

                    {

                        // a timeout means the camera is offline or similar, so we'll just say it's no longer here

                        m_cameraExists = false;

                        m_cameraError = "Unable to communicate with the configured camera";

                        break;

                    }

 

                    if (img == null) System.Threading.Thread.Sleep(250);

                } while (img == null);

            }

 

            #endregion

 

            #region --- image to web page ---

            Div container = new Div();

            container.ClassName = "centeredContainer";

 

            if (m_cameraExists)

            {

                // create an Image

                OpenNETCF.Web.Html.Image image = new OpenNETCF.Web.Html.Image(filename.Replace('\\', '/'), "Padarn Screen Capture");

 

                // set the image Style (overrides CSS if it exists)

                image.Styles.Add(new ElementStyle("border-width", 2));

                image.Styles.Add(new ElementStyle("border-style", "groove"));

 

                // add image to container

                container.Elements.Add(image);

            }

            else

            {

                Heading heading = new Heading(new RawText(m_cameraError), HeadingSize.H2);

                container.Elements.Add(heading);

            }

 

            // add container to document

            doc.Body.Elements.Add(container);

            #endregion

        }

 

        private void ShowStationaryPage(Document doc)

        {

            doc.Head.Scripts.Add(new Script(ScriptType.JavaScript, JAVA_SCRIPT, string.Empty));

            doc.Body.OnUnloadAction = "stopTimer()";

 

            doc.Body.Add(new RawText(HTML));

        }

 

        private string JAVA_SCRIPT =

            "var timer;\r\n" +