using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Threading;
using Microsoft.Win32;
using System.IO;
using Microsoft.DirectX.DirectInput;
using System.Runtime.InteropServices;
using System.Collections;
namespace Fusion_Control_Centre_UberMDX
{
public partial class MainMDX : Form
{
#region Constructor and Initialization of Fusion Control Centre Uber MDX Edition...
public MainMDX(bool showSplashScreen,
bool useBasicGraphics,
bool input_useThreading,
bool input_rapeRegistry,
bool input_useLiteVersion)
{
useThreading = input_useThreading;
SetThreadRegionalSettings(System.Threading.Thread.CurrentThread);
InitializeComponent();
DEBUG_InitializeTesting();
if (input_rapeRegistry)
{
UpdateRegistry();
}
if (showSplashScreen)
{
SetupSplashScreen();
}
MDX_Graphics_Mode = GraphicsMode.DIRECTX;
if (useBasicGraphics)
{
MDX_Graphics_Mode = GraphicsMode.GDI;
}
if (input_useLiteVersion)
{
MDX_Graphics_Mode = GraphicsMode.LITE;
}
SetupMDX_GraphicsArea();
SetupMDX_LogicSection();
SetupSpeech();
RemoteControlClass.InitializeRemoteControl(this);
COM_Initialize();
SetupTimersAndThreads();
bool USB_active = true;
try
{
if (!USB_CommunicationClass.Setup_USB_CommunicationClass())
{
USB_active = false;
}
}
catch (DllNotFoundException e)
{
USB_active = false;
}
Setup_BrainRelationship();
this.MouseDown += new MouseEventHandler(MDX_Form_MouseClick_DOWN);
this.MouseUp += new MouseEventHandler(MDX_Form_MouseClick_UP);
this.FormClosing += new FormClosingEventHandler(MainMDX_FormClosing);
this.Paint += new PaintEventHandler(MDX_Render);
this.Resize += new EventHandler(MainMDX_Resize);
if (_SCF != null)
{
_SCF.Die();
}
this.StartPosition = FormStartPosition.CenterScreen;
int _widthScreenResolution = Screen.PrimaryScreen.Bounds.Width;
int _heightScreenResolution = Screen.PrimaryScreen.Bounds.Height;
this.Location = new Point((int)(_widthScreenResolution / 2) - (int)(this.Width / 2), (int)(_heightScreenResolution / 2) - (int)(this.Height / 2));
SetupHiddenOperations();
InitializeTimersAndThreads();
ReadRegionalSettings();
DEBUG_ShowAllDebuggingWindows();
}
private void ReadRegionalSettings()
{
Regional_NumberStringSeperator = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
Regional_NumberStringSeperator = ".";
SetThreadRegionalSettings(THREAD_IO);
SetThreadRegionalSettings(THREAD_Logic);
}
private void SetThreadRegionalSettings(Thread t)
{
if (t == null) { return; }
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-US");
t.CurrentCulture = ci;
return;
}
private void DEBUG_InitializeTesting()
{
//Nothing at the moment
}
private void DEBUG_ShowAllDebuggingWindows()
{
foreach (Form _f in DEBUG_FormsToShow)
{
if (!_f.IsDisposed)
{
_f.Show();
}
}
}
private void DEBUG_HideAllDebuggingWindows()
{
foreach (Form _f in DEBUG_FormsToShow)
{
_f.Hide();
}
}
private void UpdateRegistry()
{
try
{
RegistryKey registryAppLocation = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Fusion Control Centre\MDX", RegistryKeyPermissionCheck.ReadWriteSubTree);
string[] _currentInstallPaths = registryAppLocation.GetValueNames();
//bool _isOthers = false;
bool _thisIsAlreadyAdded = false;
int max_level = 1;
string _valueName = "INSTALL_PATH";
if (_currentInstallPaths.Length > 0)
{
foreach (string _installPathTest in _currentInstallPaths)
{
if (_installPathTest.StartsWith("INSTALL_PATH_"))
{
int _tryParseINT = -1;
if (int.TryParse(_installPathTest.Substring("INSTALL_PATH_".Length), out _tryParseINT))
{
object _testPath = registryAppLocation.GetValue(_installPathTest);
if (_testPath.ToString().ToLower() == Application.ExecutablePath.ToLower())
{
max_level = _tryParseINT;
_thisIsAlreadyAdded = true;
}
else
{
string _execPath = registryAppLocation.GetValue(_installPathTest).ToString();
if (!File.Exists(_execPath))
{
registryAppLocation.DeleteValue(_installPathTest);
}
if (!_thisIsAlreadyAdded)
{
if (_tryParseINT >= max_level)
{
max_level = _tryParseINT + 1;
}
}
}
}
}
}
}
registryAppLocation.SetValue(_valueName + "_" + max_level.ToString(), (string)Application.ExecutablePath);
return;
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show("MDX does not have the neccessary permissions to write to the registry. Please close the program and run as an administrator");
}
}
public void SetupMDX_GraphicsArea()
{
if (!SetUpMDXDevice())
{
MDX_Graphics_Mode = GraphicsMode.GDI;
}
if (!ReadInConfigurationFile())
{
DisplayMessageBox("Unknown Error in Configuration File", true);
Application.Exit();
return;
}
Sort_AllGUI_by_Z_OrderDepth();
}
public void SetupMDX_LogicSection()
{
PerformLogicCommands("all");
}
#endregion
#region Configure Hidden Operations
public void SetupHiddenOperations()
{
if (!RunProgramInSystemTray)
{
this.Show();
}
else
{
this.Hide();
}
if (HideCursor)
{
Cursor.Hide();
}
else
{
Cursor.Show();
}
}
#endregion
#region Setup Splash Screen
public void SetupSplashScreen()
{
_SCF = new SplashScreenForm(this);
_SCF.Show();
_SCF.TopMost = true;
}
#endregion
#region Verbose Debug Logging
public static void MDX_DebugLogging(string SendThisStringForLogging)
{
if (Debug_VerboseLoggingEvent != null)
{
Debug_VerboseLoggingEvent(SendThisStringForLogging);
}
}
#endregion
/*
protected override void OnPaintBackground(PaintEventArgs pevent)
{
}
*/
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
UpdateDaGUI();
//device.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0f, 0);
//device.Present();
}
#region Setup MDX Device
public bool SetUpMDXDevice()
{
PresentParameters present_params = new PresentParameters();
MDX_DebugLogging("Setting Up Display");
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
if (MDX_Graphics_Mode == GraphicsMode.DIRECTX)
{
try
{
MDX_PresentParameters = new PresentParameters();
MDX_PresentParameters.Windowed = true;
MDX_PresentParameters.SwapEffect = SwapEffect.Discard;
//MDX_PresentParameters.BackBufferWidth = this.ClientSize.Width;
//MDX_PresentParameters.BackBufferHeight = this.ClientSize.Height;
//MDX_PresentParameters.PresentationInterval = PresentInterval.Immediate;
MDX_PresentParameters.PresentationInterval = PresentInterval.Default;
try
{
MDX_Device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, Microsoft.DirectX.Direct3D.CreateFlags.HardwareVertexProcessing, MDX_PresentParameters);
MDX_DebugLogging("Hardware Processing Enabled");
}
catch (Exception)
{
MDX_Device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, Microsoft.DirectX.Direct3D.CreateFlags.SoftwareVertexProcessing, MDX_PresentParameters);
MDX_DebugLogging("Software Processing Enabled");
}
//Microsoft.DirectX.DirectInput.Device _d = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse);
//_d.SetCooperativeLevel(this, CooperativeLevelFlags.Foreground | CooperativeLevelFlags.NonExclusive);
MDX_Sprite_BackgroundImages = new Sprite(MDX_Device);
MDX_Sprite_NormalLayer = new Sprite(MDX_Device);
/*
MDX_Mouse = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse);
MDX_Mouse.SetCooperativeLevel(this, CooperativeLevelFlags.Foreground | CooperativeLevelFlags.NonExclusive);
MDX_Mouse.SetDataFormat(DeviceDataFormat.Mouse);
MDX_Mouse.Properties.AxisModeAbsolute = true;
MDX_Mouse.Acquire();
*/
return true;
}
catch (Exception)
{
MDX_Graphics_Mode = GraphicsMode.GDI;
return false;
}
}
else
{
MDX_Graphics_Mode = GraphicsMode.GDI;
return false;
}
}
#endregion
#region MDX Paint Render
private void MDX_Render(object sender, PaintEventArgs e)
{
if (MDX_Device == null || MDX_Sprite_BackgroundImages == null || MDX_Sprite_NormalLayer == null)
{
return;
}
UpdateDaGUI();
}
#endregion
#region Program Closing
/*
void MainMDX_ProgramClosing(object sender, FormClosingEventArgs e)
{
try
{
USB_CommunicationClass.THREAD_SAFETY_SENDOK = false;
CloseAllOpenLogStreams();
USB_CommunicationClass.ShutOffAllOutputs();
USB_CommunicationClass.DisposeOfAllBrains();
}
catch (Exception)
{
//Error Closing the Program
MessageBox.Show("Error Closing the Program... You shouldn't be seeing this. :(", "UH OH", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
*/
/*
void MainMDX_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
USB_CommunicationClass.THREAD_SAFETY_SENDOK = false;
CloseAllOpenLogStreams();
USB_CommunicationClass.ShutOffAllOutputs();
USB_CommunicationClass.DisposeOfAllBrains();
uint successOfComRevoke = COM_Revoke();
}
catch (Exception)
{
MessageBox.Show("Error Closing the Program... You shouldn't be seeing this. :(", "UH OH", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
*/
void MainMDX_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
USB_CommunicationClass.THREAD_SAFETY_SENDOK = false;
if (useThreading)
{
THREAD_IO.Abort();
THREAD_Logic.Abort();
}
USB_CommunicationClass.ShutOffAllOutputs();
USB_CommunicationClass.DisposeOfAllBrains();
CloseAllOpenLogStreams();
uint successOfComRevoke = COM_Revoke();
}
catch (Exception ERRORCLOSINGFORM_e)
{
Console.WriteLine(ERRORCLOSINGFORM_e.ToString());
return;
}
}
private delegate void DoCloseBrains();
private event DoCloseBrains CloseProgramEvent;
#endregion
#region Setup & Initialize Timers/Threads
public void SetupTimersAndThreads()
{
if (useThreading)
{
THREAD_Logic = new Thread(THREAD_UPDATE_Logic);
THREAD_IO = new Thread(THREAD_UPDATE_IO);
THREAD_Logic.Name = "Logic Thread";
THREAD_IO.Name = "IO Thread";
THREAD_Logic.IsBackground = true;
THREAD_IO.IsBackground = true;
GUI_Timer.Tick += new EventHandler(GUI_Timer_Tick);
GUI_Timer.Enabled = false;
GUI_Timer.Interval = 50;
GC_Timer.Tick += new EventHandler(GC_Timer_Tick);
GC_Timer.Enabled = false;
GC_Timer.Interval = THREAD_GARBAGE_COLLECTION_INTERVAL;
}
else
{
MDX_DebugLogging("Initializing Timers");
LogicTimer.Tick += new EventHandler(LogicTimer_Tick);
LogicTimer.Enabled = false;
LogicTimer.Interval = THREAD_LOGIC_SLEEP_INTERVAL;
GUI_Timer.Tick += new EventHandler(GUI_Timer_Tick);
GUI_Timer.Enabled = false;
GUI_Timer.Interval = 50;
IO_Timer.Tick += new EventHandler(IO_Timer_Tick);
IO_Timer.Enabled = false;
IO_Timer.Interval = THREAD_IO_SLEEP_INTERVAL;
GC_Timer.Tick += new EventHandler(GC_Timer_Tick);
GC_Timer.Enabled = false;
GC_Timer.Interval = THREAD_GARBAGE_COLLECTION_INTERVAL;
}
}
public void InitializeTimersAndThreads()
{
if (useThreading)
{
THREAD_Logic.Start();
THREAD_IO.Start();
GUI_Timer.Enabled = true;
GC_Timer.Enabled = true;
}
else
{
LogicTimer.Enabled = true;
IO_Timer.Enabled = true;
GUI_Timer.Enabled = true;
GC_Timer.Enabled = true;
}
}
#endregion
#region Timer Events
private void LogicTimer_Tick(object sender, EventArgs e)
{
UPDATE_Logic();
}
private void IO_Timer_Tick(object sender, EventArgs e)
{
UPDATE_IO();
}
private void GUI_Timer_Tick(object sender, EventArgs e)
{
UPDATE_GUI();
}
void GC_Timer_Tick(object sender, EventArgs e)
{
GC.Collect();
}
#endregion
#region Thread Events
public void THREAD_UPDATE_Logic()
{
while (true)
{
DateTime _beginning = DateTime.Now;
UPDATE_Logic();
TimeSpan _totalTime = DateTime.Now.Subtract(_beginning);
if (_totalTime.TotalMilliseconds > THREAD_LOGIC_SLEEP_INTERVAL) { }
Thread.Sleep(THREAD_LOGIC_SLEEP_INTERVAL);
}
}
/*
public void THREAD_UPDATE_GUI()
{
while (true)
{
UPDATE_GUI();
Thread.Sleep(GUI_Timer.Interval);
}
}
*/
public void THREAD_UPDATE_IO()
{
USB_CommunicationClass.USB_CommunicationClass_LOOP();
}
/*
public void THREAD_UPDATE_Output()
{
while (true)
{
UPDATE_Output();
Thread.Sleep(OutputTimer.Interval);
}
}
public void THREAD_UPDATE_Input()
{
while (true)
{
UPDATE_Input();
Thread.Sleep(InputTimer.Interval);
}
}
*/
#endregion
#region Setup Brain Relationships
public void Setup_BrainRelationship()
{
foreach (VirtualBrainClass VB in DEBUG_VirtualBrainList)
{
foreach (BrainID _brain in AllBrains)
{
if (VB._human.ToLower() == _brain.humanName.ToLower())
{
VB.Initialize(_brain.version, this);
break;
}
}
}
foreach (BrainID _FB in AllBrains)
{
foreach (DigitalOutputChannel _doc in AllDigitalOutputs)
{
if (_doc.BrainID.ToLower() == _FB.humanName.ToLower())
{
if (_doc.Port >= 0 && _doc.Port < _FB.DigitalOutputIndexArray_EX.Length)
{
_FB.DigitalOutputIndexArray_EX[_doc.Port] = AllDigitalOutputs.IndexOf(_doc);
continue;
}
}
}
foreach (AnalogueInputChannel _aic in AllAnalogueInputs)
{
if (_aic.BrainID.ToLower() == _FB.humanName.ToLower())
{
if (_aic.Port >= 0 && _aic.Port < _FB.AnalogueInputIndexArray_EX.Length)
{
_FB.AnalogueInputIndexArray_EX[_aic.Port] = AllAnalogueInputs.IndexOf(_aic);
if (_aic.id.ToLower() == _FB.Accurate_AnalogueScalingInput_Index_ReferenceID)
{
_FB.Accurate_AnalogueScalingInput_Index = _FB.AnalogueInputIndexArray_EX[_aic.Port];
}
}
}
}
foreach (DigitalInputChannel _dic in AllDigitalInputs)
{
if (_dic.BrainID.ToLower() == _FB.humanName.ToLower())
{
if (_dic.Port >= 0 && _dic.Port < _FB.DigitalInputIndexArray_EX.Length)
{
_FB.DigitalInputIndexArray_EX[_dic.Port] = AllDigitalInputs.IndexOf(_dic);
}
}
}
}
}
#endregion
#region Update Functions
public void UPDATE_Logic()
{
PerformLogicCommands("logic");
UpdateLogs("logic");
COM_RefreshAllValues();
}
public void UPDATE_GUI()
{
UpdateDaGUI();
PerformLogicCommands("gui");
UpdateLogs("gui");
}
public void UPDATE_IO()
{
PerformLogicCommands("io");
USB_CommunicationClass.DoUSB();
UpdateLogs("io");
}
/*
public void UPDATE_Output()
{
PerformLogicCommands("output");
USB_OutputSteps();
UpdateLogs("output");
}
public void UPDATE_Input()
{
USB_InputSteps();
PerformLogicCommands("input");
UpdateLogs("input");
}
*/
#endregion
#region Degrees to Radians
public double DegreesToRadians(double inDegrees)
{
return (double)((inDegrees * Math.PI) / (180.0f));
}
#endregion
#region Error Message Box
///
/// When an error occurs, make a message box for the user
///
/// The main body text for the error message
public void DisplayMessageBox(string error)
{
if (_SCF != null)
{
_SCF.Hide();
}
if (MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
{
if (_SCF != null)
{
_SCF.Show();
}
}
}
#endregion
#region Fatal Error Message Box
///
/// Fatal Error, so display the error and then close the program
///
///
/// Should always be true when using this function
public void DisplayMessageBox(string error, bool isFatal)
{
if (_SCF != null && isFatal)
{
_SCF.Close();
}
else if (_SCF != null && !isFatal)
{
_SCF.Hide();
}
MessageBox.Show(error, "FATAL Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (isFatal)
{
//Environment.Exit(1);
Application.Exit();
return;
}
else if (_SCF != null && !isFatal)
{
_SCF.Show();
}
}
#endregion
#region Double Click System Tray Icon
private void SystemTrayNotificationIcon_DoubleClick(object sender, EventArgs e)
{
MDX_ProgramForms_Show();
this.WindowState = FormWindowState.Normal;
}
#endregion
#region Main Form Resized
void MainMDX_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
MDX_ProgramForms_Hide();
}
}
#endregion
#region Minimize To Tray
public void MDX_ProgramForms_Hide()
{
if (MinimizeToSystemTray)
{
this.Hide();
DEBUG_HideAllDebuggingWindows();
}
}
public void MDX_ProgramForms_Show()
{
this.Show();
DEBUG_ShowAllDebuggingWindows();
}
#endregion
#region System Tray Menu Clicked
private void SystemTrayContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem == SYSTRAY_CM_Restore)
{
MDX_ProgramForms_Show();
this.WindowState = FormWindowState.Normal;
}
else if (e.ClickedItem == SYSTRAY_CM_Close)
{
this.Close();
}
}
#endregion
}
}