//
        //
        //
        //
        // ****             Update Curve Definition                 ****
        //
        private void UpdateCurveDefinition(ZedGraphControl zg1, CurveDefinition zNewCurve)
        {
            CurveItem curve = zg1.GraphPane.CurveList[zNewCurve.CurveName];

            if (curve == null)
            {   // curve name does not yet exist.  User wants us to create a new one.
                if (zNewCurve.Type == CurveDefinition.CurveType.Curve)
                {
                    curve = zg1.GraphPane.AddCurve(zNewCurve.CurveName, new PointPairList(), zNewCurve.CurveColor, zNewCurve.Symbol);
                }
                //else if (zNewCurve.Type == CurveDefinition.CurveType.Bar)
                //	curve = zg1.GraphPane.AddBar(zNewCurve.CurveName, new PointPairList(), zNewCurve.CurveColor, zNewCurve.Symbol);
                else
                {
                    return;                     // failed to create new curve
                }
            }
            // Update properties of found curve.
            if (zNewCurve.Type == CurveDefinition.CurveType.Curve)
            {
                LineItem li = (LineItem)curve;
                li.Line.Style     = zNewCurve.DashStyle;
                li.Line.Width     = zNewCurve.CurveWidth;
                li.Symbol.Type    = zNewCurve.Symbol;
                li.Symbol.Fill    = new Fill(zNewCurve.SymbolFillColor);
                li.Symbol.Size    = zNewCurve.SymbolSize;
                li.Line.IsVisible = zNewCurve.IsLineVisible;
                curve.Color       = zNewCurve.CurveColor;
                if (!String.IsNullOrEmpty(zNewCurve.GraphName))
                {
                    zg1.Name = zNewCurve.GraphName;
                }
            }
            else if (zNewCurve.Type == CurveDefinition.CurveType.Bar)
            {
                // TODO: implement bars
                if (!String.IsNullOrEmpty(zNewCurve.GraphName))
                {
                    zg1.Name = zNewCurve.GraphName;
                }
            }
        }//UpdateCurveDefintion()
        }// InitializeEngine()

        //
        //
        // ****          Process Event           ****
        //
        public void ProcessEvent(EventArgs e)
        {
            // Initialize and validate
            if (!m_IsGraphsInitialized)
            {   // Graphs not initialized yet. Just store these events.
                m_InitialEvents.Add(e);
                return;
            }
            else if (m_InitialEvents.Count > 0)
            {   // The graphs have just been initialized, so
                // lets extract all the previously stored initial events.
                List <EventArgs> events = new List <EventArgs>();
                events.AddRange(m_InitialEvents);       // add already acrued events.
                m_InitialEvents.Clear();                // clearing this signals we are ready for normal operation.
                events.Add(e);                          // add the latest event also.
                foreach (EventArgs anEvent in events)
                {
                    ProcessEvent(anEvent);
                }
            }
            if (e.GetType() != typeof(EngineEventArgs))
            {
                return;
            }
            //
            // Process Engine Events
            //
            EngineEventArgs eArgs = (EngineEventArgs)e;

            EngineEventArgs.EventType   eventType   = eArgs.MsgType;
            EngineEventArgs.EventStatus eventStatus = eArgs.Status;
            if (eventStatus != EngineEventArgs.EventStatus.Confirm)
            {
                return;                                 // we only process confirmations.
            }
            if (eArgs.DataObjectList != null)
            {
                foreach (object o in eArgs.DataObjectList)
                {
                    // *****************************************
                    // ****		Curve Definitiion List		****
                    // *****************************************
                    Type dataType = o.GetType();
                    //if (dataType == typeof(List<CurveDefinition>))
                    if (dataType == typeof(CurveDefinitionList))
                    {   // Given a list of curve definitions, update pre-defined curves,
                        // or create new curves.  These must be created by the windows thread.
                        // These are usually only received at the start of the run when all parameters are broadcasted.
                        List <CurveDefinition>            list = ((CurveDefinitionList)o).CurveDefinitions;
                        Dictionary <int, EngineEventArgs> requestedGraphRequests = new Dictionary <int, EngineEventArgs>(); // place to put CurveDefs for not yet created graphs.
                        foreach (CurveDefinition cDef in list)
                        {
                            ZedGraphControl zg1;
                            lock (GraphListLock)
                            {
                                if (!m_GraphList.TryGetValue(cDef.GraphID, out zg1))
                                {               // Since we can't find this GraphID, request it to be created below.
                                    m_ZedGraphIDRequested.Add(cDef.GraphID);
                                    zg1 = null; // this signals that graph doesn't exit.
                                }
                            }
                            if (zg1 == null && !requestedGraphRequests.ContainsKey(cDef.GraphID))
                            {                                                     // We couldn't find GraphID, so request it to be created it now!
                                // Also make sure we only request it once thru this loop, just to save time.
                                AddGraph(this, eArgs);                            // Asynch call will call ProcessEvent() again.
                                EngineEventArgs newEvent = new EngineEventArgs(); // Event we will restack until after graph exists.
                                newEvent.DataObjectList = new List <object>();
                                newEvent.Status         = EngineEventArgs.EventStatus.Confirm;
                                requestedGraphRequests.Add(cDef.GraphID, newEvent);// Mark this ID as having just been requested.
                            }
                            if (requestedGraphRequests.ContainsKey(cDef.GraphID))
                            {             // This is a curve for a graph we just requested... push onto wait list.
                                requestedGraphRequests[cDef.GraphID].DataObjectList.Add(cDef);
                                continue; // skip
                            }

                            UpdateCurveDefinition(zg1, cDef);
                        }//next curveDefn
                        // Push any unfulfilled requests back onto queue.
                        foreach (EngineEventArgs eeArgs in requestedGraphRequests.Values)
                        {
                            m_InitialEvents.Add(eeArgs);
                        }
                    }
                    // *****************************************
                    // ****			ZGraphPoints		    ****
                    // *****************************************
                    else if (dataType == typeof(ZGraphPoints))
                    {   // This is a list of ZGraphPoint objects. This message is from the AllParameter broadcast
                        // at the beginning of the run.  A new ZGraphControl will request all parameter values
                        // only when first created.   Therefore, if we are an old ZGraphControl, it probably is not
                        // for us.
                        if (m_LoadedHistory)
                        {
                            return;
                        }
                        m_LoadedHistory = true;
                        List <ZGraphPoint> pointList = ((ZGraphPoints)o).Points;
                        foreach (ZGraphPoint zpt in pointList)
                        {
                            ZedGraphControl zg1;
                            if (!m_GraphList.TryGetValue(zpt.GraphID, out zg1))
                            {   // No currently existing graph with this id.
                                continue;
                            }
                            CurveItem curve = null;
                            if (zg1.GraphPane != null)
                            {
                                curve = zg1.GraphPane.CurveList[zpt.CurveName];
                                if (curve == null)
                                {       // a new curve showed up - create a new curve, and plot this point anyway.
                                    Color newColor = m_DefaultColors[zg1.GraphPane.CurveList.Count % m_DefaultColors.Length];
                                    curve = zg1.GraphPane.AddCurve(zpt.CurveName, new PointPairList(), newColor, SymbolType.None);
                                }
                            }
                            // Add/replace points in the plot.
                            IPointListEdit ip = null;
                            if (curve != null)
                            {
                                ip = curve.Points as IPointListEdit;
                            }
                            if (ip != null)
                            {
                                if (zpt.IsReplaceAtX)
                                {                                      // This is a request to replace point with new one.
                                    int foundIndex = -1;
                                    for (int i = 0; i < ip.Count; ++i) // search for X-value of point to replace
                                    {
                                        if (ip[i].X == zpt.X)          // very unsafe
                                        {
                                            foundIndex = i;
                                            break;                                              // stop looking
                                        }
                                    }
                                    if (foundIndex > -1)
                                    {
                                        ip[foundIndex].Y = zpt.Y;
                                    }
                                    else
                                    {
                                        ip.Add(zpt.X, zpt.Y);
                                        // sort?
                                    }
                                }
                                else
                                {
                                    ip.Add(zpt.X, zpt.Y);               // simple serial addition of new data point.
                                }
                            }
                        }//next zpt
                    }
                    // *****************************************
                    // ****			List<ZGraphPoint>		****
                    // *****************************************

                    /*
                     * else if (dataType == typeof(List<ZGraphPoint>))
                     * {   // This is a list of ZGraphPoints.  This message is from the AllParameter broadcast
                     *  // at the beginning of the run.  A new ZGraphControl will request all parameter values
                     *  // only when first created.   Therefore, if we are an old ZGraphControl, it probably is not
                     *  // for us.
                     *  List<ZGraphPoint> pointList = (List<ZGraphPoint>) o;
                     *  foreach (ZGraphPoint zpt in pointList)
                     *  {
                     *      ZedGraphControl zg1;
                     *      if (!m_GraphList.TryGetValue(zpt.GraphID, out zg1))
                     *      {	// No currently existing graph with this id.
                     *          continue;
                     *      }
                     *      CurveItem curve = null;
                     *      if (zg1.GraphPane != null)
                     *      {
                     *          curve = zg1.GraphPane.CurveList[zpt.CurveName];
                     *          if (curve == null)
                     *          {	// a new curve showed up - create a new curve, and plot this point anyway.
                     *              Color newColor = m_DefaultColors[zg1.GraphPane.CurveList.Count % m_DefaultColors.Length];
                     *              curve = zg1.GraphPane.AddCurve(zpt.CurveName, new PointPairList(), newColor, SymbolType.None);
                     *          }
                     *      }
                     *      // Add/replace points in the plot.
                     *      IPointListEdit ip = null;
                     *      if (curve != null)
                     *          ip = curve.Points as IPointListEdit;
                     *      if (ip != null)
                     *      {
                     *          if (zpt.IsReplaceAtX)
                     *          {	// This is a request to replace point with new one.
                     *              int foundIndex = -1;
                     *              for (int i = 0; i < ip.Count; ++i)	// search for X-value of point to replace
                     *                  if (ip[i].X == zpt.X)			// very unsafe
                     *                  {
                     *                      foundIndex = i;
                     *                      break;						// stop looking
                     *                  }
                     *              if (foundIndex > -1)
                     *                  ip[foundIndex].Y = zpt.Y;
                     *              else
                     *              {
                     *                  ip.Add(zpt.X, zpt.Y);
                     *                  // sort?
                     *              }
                     *
                     *          }
                     *          else
                     *              ip.Add(zpt.X, zpt.Y);		// simple serial addition of new data point.
                     *      }
                     *  }//next zpt
                     * }
                     */
                    // *****************************************
                    // ****			Curve Definition		****
                    // *****************************************
                    else if (dataType == typeof(CurveDefinition))
                    {
                        CurveDefinition zNewCurve = (CurveDefinition)o;
                        ZedGraphControl zg1;
                        if (!m_GraphList.TryGetValue(zNewCurve.GraphID, out zg1))
                        {             // New graph ID!
                            continue; // TODO: Create new graph on the fly.
                        }
                        UpdateCurveDefinition(zg1, zNewCurve);
                    }
                    // *****************************************
                    // ****			ZGraphPoint			    ****
                    // *****************************************
                    else if (dataType == typeof(ZGraphText))
                    {
                        ZGraphText      zpt = (ZGraphText)o;
                        ZedGraphControl zg1;
                        if (!m_GraphList.TryGetValue(zpt.GraphID, out zg1))
                        {       // No currently existing graph with this id.
                            continue;
                        }

                        TextObj text = new TextObj(zpt.Text, zpt.X, zpt.Y);

                        text.FontSpec.Angle  = zpt.FontAngle;
                        text.Location.AlignH = zpt.FontAlignH;
                        text.Location.AlignV = zpt.FontAlignV;

                        text.FontSpec.Size             = zpt.FontSize;
                        text.FontSpec.Border.IsVisible = zpt.FontBorderIsVisible;
                        text.FontSpec.Fill.IsVisible   = zpt.FontFillIsVisible;

                        zg1.GraphPane.GraphObjList.Add(text);
                    }
                    // *****************************************
                    // ****			ZGraphPoint			    ****
                    // *****************************************
                    else if (dataType == typeof(ZGraphPoint))
                    {
                        ZGraphPoint     zpt = (ZGraphPoint)o;
                        ZedGraphControl zg1;
                        if (!m_GraphList.TryGetValue(zpt.GraphID, out zg1))
                        {       // No currently existing graph with this id.
                            continue;
                        }
                        CurveItem curve = null;
                        if (zg1.GraphPane != null)
                        {
                            curve = zg1.GraphPane.CurveList[zpt.CurveName];
                            if (curve == null)
                            {   // a new curve showed up - create a new curve, and plot this point anyway.
                                Color newColor = m_DefaultColors[zg1.GraphPane.CurveList.Count % m_DefaultColors.Length];
                                curve = zg1.GraphPane.AddCurve(zpt.CurveName, new PointPairList(), newColor, SymbolType.None);
                            }
                        }
                        // Add/replace points in the plot.
                        IPointListEdit ip = null;
                        if (curve != null)
                        {
                            ip = curve.Points as IPointListEdit;
                        }
                        if (ip != null)
                        {
                            if (zpt.IsReplaceAtX)
                            {                                      // This is a request to replace point with new one.
                                int foundIndex = -1;
                                for (int i = 0; i < ip.Count; ++i) // search for X-value of point to replace
                                {
                                    if (ip[i].X == zpt.X)          // very unsafe
                                    {
                                        foundIndex = i;
                                        break;                                          // stop looking
                                    }
                                }
                                if (foundIndex > -1)
                                {
                                    ip[foundIndex].Y = zpt.Y;
                                }
                                else
                                {
                                    ip.Add(zpt.X, zpt.Y);
                                    // sort?
                                }
                            }
                            else
                            {
                                ip.Add(zpt.X, zpt.Y);           // simple serial addition of new data point.
                            }
                        }
                    }// ZPoint
                }
                m_IsUpdateRequired = true;
                //Regenerate(this, EventArgs.Empty);
            } //if e.DataObjectList is empty
        }     // ProcessEvent()