Subversion Repositories amilis

Rev

Blame | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Anoto;
using System.Threading;
//using Ivy;
using IvyBus;
using System.Media;
using AnotoData;
//using Data;

using Microsoft.Ink;


namespace Anoto
{


    public partial class FormAnotoSupervision : Form
    {
        Recognizer TheRecognizer;
        RecognizerContext TheRecognizerContext;

        //    AppDatabase TheData;
        DateTime LastDataUpdate;

        private SoundPlayer SoundPenDown = new SoundPlayer();
        private SoundPlayer SoundPenUp = new SoundPlayer();

        private const int MAX_LOG_LENGTH = 100;

        Anoto.GenericStreamer.PenManagerClass PenManager;

        //    AnotoStrip[] Strips;
        List<AnotoHotArea> HotAreas;

        AnotoRadarScreen TheAnotoRadarScreen;
        AnotoStripBoard TheAntotoStripBoard;

        Dictionary<string, List<PointF>> PensPoints;
        Dictionary<string, Brush> PensBrush;
        Dictionary<string, Pen> Pens;

        List<AnotoPen> AnotoPens;

        Mutex mutex;
        Random Rnd;


        Bitmap DrawingArea;
        private SolidBrush TranparentBlack;


        XMLStateMachine StateMAchine;

        public FormAnotoSupervision()
        {
            InitializeComponent();

            StateMAchine = new XMLStateMachine();
            StateMAchine.StateTable = "XMLStates.xml";
            StateMAchine.CurrentState = "Start";

            //       TheData = new AppDatabase(TheIvyBus);
        }

        void TheIvyDomain_DomainChanged(object sender, EventArgs e)
        {
            TheIvyBus.ivy.Stop();
            TheIvyBus.ivy.Start(TheIvyDomain.Domain);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            //      TheRecognizer.;
            //TheRecognizer.CreateRecognizerContext();

            TranparentBlack = new SolidBrush(Color.FromArgb(100, 0, 0, 0));

            TheIvyDomain.Location = new Point(0, 30);

            DrawingArea = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = DrawingArea;


            //Start IVY
            TheIvyBus.ivy.Start(TheIvyDomain.Domain);

            TheIvyDomain.DomainChanged += new EventHandler(TheIvyDomain_DomainChanged);

            this.Controls.Add(TheIvyDomain);

            AnotoPens = new List<AnotoPen>();

            PenManager = new Anoto.GenericStreamer.PenManagerClass();

            PenManager.PenConnected += new Anoto.GenericStreamer._IPenManagerEvents_PenConnectedEventHandler(pm_PenConnected);
            PenManager.PenDisconnected += new GenericStreamer._IPenManagerEvents_PenDisconnectedEventHandler(PenManager_PenDisconnected);
            PenManager.NewCoordinate += new Anoto.GenericStreamer._IPenManagerEvents_NewCoordinateEventHandler(PenManager_NewCoordinate);
            PenManager.PenDown += new Anoto.GenericStreamer._IPenManagerEvents_PenDownEventHandler(PenManager_PenDown);
            PenManager.PenUp += new Anoto.GenericStreamer._IPenManagerEvents_PenUpEventHandler(PenManager_PenUp);
            PenManager.Start();

            mutex = new Mutex();

            InitDictionary();

            Rnd = new Random();

            AnotoStrip[] Strips = AnotoStrip.LoadFileStrip("Strips.csv");
            HotAreas = new List<AnotoHotArea>();
            foreach (var strip in Strips)
            {
                HotAreas.Add(strip);
            }

            TheAnotoRadarScreen = new AnotoRadarScreen();
            HotAreas.Add(TheAnotoRadarScreen);

            TheAntotoStripBoard = new AnotoStripBoard();
            HotAreas.Add(TheAntotoStripBoard);


            listBoxHotAreas.Items.Clear();

            foreach (var ha in HotAreas)
            {
                listBoxHotAreas.Items.Add(ha);
            }

            //Load sounds
            LoadSounds();
        }

        private void LoadSounds()
        {
            this.SoundPenDown.SoundLocation = "PenDown.wav";
            this.SoundPenDown.LoadAsync();
            this.SoundPenUp.SoundLocation = "PenUp.wav";
            this.SoundPenUp.LoadAsync();
        }



        private void InitDictionary()
        {
            PensPoints = new Dictionary<string, List<PointF>>();
            PensBrush = new Dictionary<string, Brush>();
            Pens = new Dictionary<string, Pen>();
        }

        #region Pen management/ events

        void pm_PenConnected(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, string productName, ushort pid)
        {
            AnotoPen pen = new AnotoPen(penSerial, PenType, time, productName, pid);
            AnotoPens.Add(pen);

            this.Invoke(new MethodInvoker(delegate()
            {
                listBoxAnotoPens.Items.Add(pen);
                AddLog("Pen connected " + penSerial + " " + PenType.ToString() + " " + productName);

            }));

            //  Console.WriteLine("Pen connected " + penSerial + " " + PenType.ToString() + " " + productName);
            if (!PensPoints.ContainsKey(penSerial))
                PensPoints.Add(penSerial, new List<PointF>());
            else
                PensPoints[penSerial] = new List<PointF>();

            if (!PensBrush.ContainsKey(penSerial))
                PensBrush.Add(penSerial, new SolidBrush(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255))));
            else
                PensBrush[penSerial] = new SolidBrush(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255)));

            if (!Pens.ContainsKey(penSerial))
                Pens.Add(penSerial, new Pen(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255))));
            else
                Pens[penSerial] = new Pen(Color.FromArgb(255, Rnd.Next(255), Rnd.Next(255), Rnd.Next(255)));
        }

        void PenManager_PenDisconnected(string penSerial, GenericStreamer.PenType PenType, ulong time)
        {
            this.Invoke(new MethodInvoker(delegate()
            {
                mutex.WaitOne();
                AnotoPen p = null;
                foreach (AnotoPen item in listBoxAnotoPens.Items)
                {
                    if (item.PenSerial == penSerial)
                        p = item;
                }
                if (p != null)
                {
                    listBoxAnotoPens.Items.Remove(p);
                    AddLog("Pen Disconnected " + penSerial + " " + PenType.ToString());

                }
                mutex.ReleaseMutex();
            }));
        }

        List<List<PointF>> InkMarks = new List<List<PointF>>();
        DateTime LastDateTimePenUp = DateTime.Now;
        /// <summary>
        /// After one second, the trail is no more valid
        /// </summary>
        int MaxMillisecondForNewtrail = 1000;

        void PenManager_PenUp(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, byte penDownSeqNbr, int isSpcdGenerated)
        {
            this.Invoke(new MethodInvoker(delegate()
         {
             AddLog("Pen Up " + penSerial + " ");
             if (checkBoxEnableSound.Checked)
                 SoundPenUp.Play();
             //    Console.WriteLine("Pen Up " + penSerial + " time " + time);

             if ((DateTime.Now - LastDateTimePenUp).TotalMilliseconds > MaxMillisecondForNewtrail)
             {
                 //MaxMillisecondForNewtrail second has past since the last trail
                 //Erase previous Data
                 InkMarks = new List<List<PointF>>();
             }
             //Copie the data the the current text recognizer
             List<PointF> tmpLst = new List<PointF>();
             foreach (var pt in PensPoints[penSerial])
             {
                 tmpLst.Add(pt);
             }
             InkMarks.Add(tmpLst);
             //Try to recogize It
             TryRecognition();

             LastDateTimePenUp = DateTime.Now;

             pictureBox1.Invalidate();
         }));
        }

        private void TryRecognition()
        {
            // Declare a new TabletPropertyDescriptionCollection (this is new in 1.7)
            TabletPropertyDescriptionCollection tpdc = new TabletPropertyDescriptionCollection();

            // Define the X and Y extents for this TabletPropertyDescriptionCollection
            TabletPropertyMetrics tpmX = new TabletPropertyMetrics();
            tpmX.Maximum = AnotoData.AnotoHotArea.MaxX;
            TabletPropertyMetrics tpmY = new TabletPropertyMetrics();
            tpmY.Maximum = tpmX.Maximum = AnotoData.AnotoHotArea.MaxY;

            // Define the NormalPressure for the Tablet PropertyDescriptionCollection
            TabletPropertyMetrics tpmNP = new TabletPropertyMetrics();
            // This defines 1024 levels of pressure
            tpmNP.Maximum = 1024;

            TabletPropertyMetrics tpmSt = new TabletPropertyMetrics();

            // Add each of the propertyMetrics to the TabletPropertyDescriptionCollection
            // This defines what the data stream will look like, in this case (X, Y, NP)
            tpdc.Add(new TabletPropertyDescription(PacketProperty.X, tpmX));
            tpdc.Add(new TabletPropertyDescription(PacketProperty.Y, tpmY));
            //  tpdc.Add(new TabletPropertyDescription(PacketProperty.TimerTick, tpmSt));
            //  tpdc.Add(new TabletPropertyDescription(PacketProperty.NormalPressure, tpmNP));

            InkCollector myInkCollector = new InkCollector();

            bool hasValideStrokes = false;
            foreach (var stroke in InkMarks)
            {
                if (stroke.Count > 0)
                {
                    Point point;
                    Point[] pts = new Point[stroke.Count];
                    int[] data = new int[stroke.Count * tpdc.Count];
                    int index = 0;
                    int data_index = 0;

                    foreach (PointF pt in stroke)
                    {

                        int x = (int)(pt.X * AnotoData.AnotoHotArea.MaxX);
                        data.SetValue(x, data_index++);
                        int y = (int)(pt.Y * AnotoData.AnotoHotArea.MaxY);
                        data.SetValue(y, data_index++);
                        //?????
                        //   data.SetValue(1000 + 100 * data_index , data_index++);
                        //    data.SetValue(512, data_index++);
                        point = new Point(x, y);
                        pts.SetValue(point, index++);
                        hasValideStrokes = true;
                    }

                    //Convert this array of ink space points to pixels.
                    //myInkCollector.Renderer.PixelToInkSpace(inkArea.Handle, ref pts);
                    //Stroke stroke = myInkCollector.Ink.CreateStroke(pts);
                    Stroke inkStroke = myInkCollector.Ink.CreateStroke(data, tpdc);
                    myInkCollector.Ink.Strokes.Add(inkStroke);
                }
            }
            if (hasValideStrokes)
            {
                TheRecognizerContext = new RecognizerContext();
                RecognitionStatus recognitionStatus;
                //TheRecognizerContext.Factoid = Microsoft.Ink.Factoid.Number+"|" + Microsoft.Ink.Factoid.LowerChar
                //    + "|" + Microsoft.Ink.Factoid.UpperChar;// "";
                TheRecognizerContext.Factoid = "(0|1|2|3|4|5|6|7|8|9|)";
                TheRecognizerContext.RecognitionFlags = RecognitionModes.Coerce;
                TheRecognizerContext.Strokes = myInkCollector.Ink.Strokes;

                RecognitionResult rr = TheRecognizerContext.Recognize(out recognitionStatus);
                if (rr != null)
                    textBoxRecognition.Text = rr.ToString();
            }
            /*
                        //throw new NotImplementedException();
                        RecognitionStatus recognitionStatus;
                        //Create the stroke collection
                        Strokes strokes;
                        Point[] pts = new Point[InkMarks.Count];
                        int index = 0;
                        foreach (var p in InkMarks)
                        {
                            pts[index] = new Point((int)(p.X * AnotoData.AnotoHotArea.MaxX),
                                                   (int)(p.X * AnotoData.AnotoHotArea.MaxY)
                                                  );
                            index++;
                        }

                        Stroke stroke = null;
                        stroke.SetPoints(pts);

                        TheRecognizerContext.Strokes.Add(stroke);

                        TheRecognizerContext.Recognize(out recognitionStatus);*/

        }

        void PenManager_PenDown(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, byte penDownSeqNbr, Anoto.GenericStreamer.PenTipType PenTipType, int isValidColor, byte r, byte g, byte b, int isSpcdGenerated)
        {
            //  Console.WriteLine("Pen Down " + penSerial + " time " + time);
            this.Invoke(new MethodInvoker(delegate()
           {
               mutex.WaitOne();
               PensPoints.Remove(penSerial);

               PensPoints.Add(penSerial, new List<PointF>());
               AddLog("Pen Down " + penSerial + " ");

               if (checkBoxEnableSound.Checked)
                   SoundPenDown.Play();
               mutex.ReleaseMutex();
           }));
        }

        void PenManager_NewCoordinate(string penSerial, Anoto.GenericStreamer.PenType PenType, ulong time, string page, int x, int y, byte imgSeqNbr, byte force)
        {
            this.Invoke(new MethodInvoker(delegate()
         {
             mutex.WaitOne();
             PensPoints[penSerial].Add(AnotoHotArea.GetHomogeneousCoordinate(x, y));
             mutex.ReleaseMutex();

             //  Console.WriteLine("Pen NewCoordinate " + penSerial + " time " + time + " x " + x + " y " + y);

             if ((DateTime.Now - LastDataUpdate).TotalMilliseconds > 100)
             {
                 PopulateGraphicalData(page, x, y, force);
                 LastDataUpdate = DateTime.Now;
             }

             PopulateData(penSerial, page, x, y, force);
         }));
        }

        #endregion

        private void AddLog(string p)
        {
            listBoxEvents.Items.Insert(0, p + " " + DateTime.Now.ToString("HH:mm:ss"));

            if (listBoxEvents.Items.Count > MAX_LOG_LENGTH)
                listBoxEvents.Items.RemoveAt(listBoxEvents.Items.Count - 1);
        }

        private void PopulateGraphicalData(string page, int x, int y, byte force)
        {
            this.Invoke(new MethodInvoker(delegate()
            {
                SetProgressBarValue(progressBarX, x);
                SetProgressBarValue(progressBarY, y);
                SetProgressBarValue(progressBarForce, (int)force);

                labelX.Text = "X: " + x;
                labelY.Text = "Y: " + y;

                labelPage.Text = page;

                pictureBox1.Invalidate();
            }));
        }

        public AnotoHotArea GetHotArea(int x, int y, string page)
        {
            AnotoHotArea result = null;
            foreach (var s in HotAreas)
            {
                if (s.IsInside(x, y, page))//  AnotoHotArea.PagesIP[s.PageIndex] == page)
                {
                    return s;
                }
            }
            return result;
        }

        private void PopulateData(string penSerial, string page, int x, int y, byte force)
        {
            this.Invoke(new MethodInvoker(delegate()
            {
                //Find the Strip name
                // AnotoHotArea hotArea = AnotoHotArea
                AnotoHotArea hotArea = GetHotArea(x, y, page);

                if (hotArea is AnotoStrip)
                {
                    AnotoStrip strip = (AnotoStrip)hotArea;
                    SubCategories cell = strip.GetStripArea(x, y);
                    labelStripInfo.Text = cell.ToString() + " : " + strip.GetTextForCell(cell)

                         + Environment.NewLine + " " + strip.ToString();
                    //       TheIvyBus.SendMsg("SelectionEvent acc=bordeaux wp=WP1 role=TC Flight=" + strip.SSR);

                    //Halo
                    if (LastSSR != strip.SSR)
                    {
                        TheIvyBus.SendMsg("SelectionEvent Flight=" + LastSSR + " Perform=False");
                        string ivySMG = "SelectionEvent Flight=" + strip.SSR + " Perform=True";
                        LastSSR = strip.SSR;
                        TheIvyBus.SendMsg(ivySMG);
                        AddLog(ivySMG);
                    }


                    /*  if ((cell != StateMachineCurrentCell) || (StateMachineCurrentStrip != strip))
                      {
                          Console.WriteLine("New Action");
                          //Test if new message:
                          StateMachineInput(cell, strip);                    
                      }*/

                }

                if (hotArea is AnotoRadarScreen)
                {
                    AnotoRadarScreen screen = (AnotoRadarScreen)hotArea;
                    labelStripInfo.Text = "Screen";
                    //send the pen down to the SimpleRadar Screen

                    screen.SendIvyMsg(penSerial, x, y, page, TheIvyBus);

                };

                if (hotArea is AnotoStripBoard)
                {
                    AnotoStripBoard stripBoard = (AnotoStripBoard)hotArea;
                    labelStripInfo.Text = "Strip Board";
                }
            }));
        }


        private AnotoStrip StateMachineCurrentStrip;
        private SubCategories StateMachineCurrentCell;

        string LastAlidadeStart = "";
        string LastAlidadeStop = "";

        string LastSSR = "";

        public void DisplayAlidade(string start, string stop)
        {
            if (!string.IsNullOrEmpty(LastAlidadeStart))
            {
                //hide the previous alidate
                TheIvyBus.SendMsg("DistanceFeedbackOff acc=bordeaux wp=WP1 role=TC Start=" + LastAlidadeStart + " End=" + LastAlidadeStop);
            }

            //If the same previous start and stop do nothing -> remove the alidade
            if (!((start == LastAlidadeStart) && (stop == LastAlidadeStop)))
            {
                //Show the new alidade
                TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + start + " End=" + stop);

                LastAlidadeStop = stop;
                LastAlidadeStart = start;

            }
            else
            {
                LastAlidadeStop = "";
                LastAlidadeStart = "";
            }
        }


        public void StateMachineInput(SubCategories cell, AnotoStrip strip)
        {
            StateMachineCurrentStrip = strip;
            StateMachineCurrentCell = cell;
            string ivySMG = "";
            if (StateMAchine.Next(cell.ToString()) != String.Empty)
            {
                Console.WriteLine(StateMAchine.Action);
                //New state
                switch (StateMAchine.Action)
                {
                    case "Hilight":
                        //Send IVY Selection event
                        ivySMG = "SelectionEvent Flight=" + strip.SSR + " Perform=True";
                        TheIvyBus.SendMsg(ivySMG);
                        AddLog(ivySMG);
                        break;
                    case "AlidadeInfoInfo":
                        //Send IVY Selection event
                        DisplayAlidade(StateMachineCurrentStrip.SSR, strip.SSR);
                        // TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.SSR + " End=" + strip.SSR);
                        break;
                    case "AlidadeInfoBeacon":
                        //Send IVY Selection event
                        DisplayAlidade(StateMachineCurrentStrip.SSR, strip.GetTextForCell(cell));
                        //     TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.SSR + " End=" + strip.GetTextForCell(cell));
                        break;

                    case "AlidadeBeaconInfo":
                        //Send IVY Selection event
                        DisplayAlidade(StateMachineCurrentStrip.GetTextForCell(StateMachineCurrentCell), strip.SSR);
                        //    TheIvyBus.SendMsg("DistanceFeedbackOn acc=bordeaux wp=WP1 role=TC Start=" + StateMachineCurrentStrip.GetTextForCell(StateMachineCurrentCell) + " End=" + strip.SSR);
                        break;

                    default:
                        break;
                }


            };
        }



        void SetProgressBarValue(ProgressBar pb, int val)
        {
            if (val < pb.Minimum)
                pb.Minimum = val;
            if (val > pb.Maximum)
                pb.Maximum = val;
            pb.Value = val;
        }


        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            PenManager.Stop();
        }


        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            //draw the dots
            Graphics g = e.Graphics;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            g.FillRectangle(Brushes.White, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));

            mutex.WaitOne();

            float scale = 15;
            Pen penPreviousStrokes = new Pen(Brushes.Black);
            foreach (var pts in InkMarks)
            {
                Point[] p = new Point[pts.Count];
                int index = 0;
                foreach (var l in pts)
                {
                    p[index] = new Point((int)(l.X * pictureBox1.Width )  ,
                        (int)(l.Y * pictureBox1.Height));
                    index++;
                }
                if ( p.Length > 1)
                      g.DrawLines(penPreviousStrokes, p);
            }

           
                        foreach (var pen in PensPoints)
                        {
                            //if (pen.Value.Count > 1)
                            //    g.DrawLines(Pens[pen.Key], pen.Value.ToArray());

                            foreach (var point in pen.Value)
                            {
                                float x = pictureBox1.Width * point.X;
                                float y = pictureBox1.Height * point.Y;

                                g.FillEllipse(TranparentBlack, x, y, 4, 4);
                            }

                            if (pen.Value.Count != 0)
                                PopulateData("", "", (int)pen.Value.Last().X, (int)pen.Value.Last().Y, 0);
                        }
             

            mutex.ReleaseMutex();
        }


        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            TheIvyBus.ivy.Stop();
        }

        private void listBoxHotAreas_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBoxHotAreas.SelectedItem != null)
            {
                PropertyAnotoHotArea.SelectedObject = (AnotoHotArea)listBoxHotAreas.SelectedItem;
            }
        }

        private void buttonPlay_Click(object sender, EventArgs e)
        {
            SoundPenDown.Play();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SoundPenUp.Play();
        }


    }


}