using MDS.Controls;
using MDS.DataModels;
using MDS.Units;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace MDS
{
/// <summary>
/// Логика взаимодействия для App.xaml
/// </summary>
public partial class App : Application, INotifyPropertyChanged
{
public enum Mode { Demo, Study, Training, Exam, Quiz};
private static string _client;
private static string _workplace;
private static bool _checker;
public static bool Checker
{
set
{
if (value != _checker)
{
_checker = value;
}
}
get { return _checker; }
}
private static ObservableCollection
<Client
> _clients
= new ObservableCollection
<Client
>();
public static ObservableCollection<Client> Clients
{
get { return _clients; }
}
public static Frame MainFrame;
private static TelnetDotNet Telnet;
public static Assembly CurrentDevice;
private static ObservableCollection<Unit> _units;
public static ObservableCollection<Unit> Units
{
get { return _units; }
private set
{
if (value != _units)
{
_units = value;
}
}
}
private static Mode _currentMode;
public static Mode CurrentMode
{
get { return _currentMode; }
set
{
if (value != _currentMode)
{
_currentMode = value;
}
}
}
private static Random rand
= new Random
();
public static Random Rand
{
get { return rand; }
}
private static Tutorial activeTutorial;
public static Tutorial ActiveTutorial
{
get { return activeTutorial; }
set
{
if (value != activeTutorial)
{
activeTutorial = value;
if(activeTutorial.RandValues!=null)
{
foreach(var val in activeTutorial.RandValues)
{
val.Min = RandVarReplace(val.Min, activeTutorial.RandValues);
val.Max = RandVarReplace(val.Max, activeTutorial.RandValues);
val.Value = Rand.Next(int.Parse(val.Min), int.Parse(val.Max));
if (val.Mod != 0)
val.Value = val.Value - val.Value % val.Mod;
}
}
activeTutorial.ExamDescription = RandVarReplace(activeTutorial.ExamDescription, activeTutorial.RandValues);
foreach (var step in activeTutorial.Steps)
{
step.Title = RandVarReplace(step.Title, activeTutorial.RandValues);
step.Command = RandVarReplace(step.Command, activeTutorial.RandValues);
if(step.Conditions!=null)
{
foreach(var cond in step.Conditions)
cond.Value = RandVarReplace(cond.Value, activeTutorial.RandValues);
}
}
}
}
}
public static string RandVarReplace(string text, List<RandValue> values)
{
string output = text;
if (values != null)
{
for (int i = 0; i < values.Count(); i++)
output = output.Replace("[" + i + "]", values[i].Value.ToString());
}
return output;
}
public static Window TutorialWindow;
public App()
{
Units
= new ObservableCollection
<Unit
>();
Telnet
= new TelnetDotNet
();
Telnet.MessageRecieved += Telnet_MessageRecieved;
Current.Exit += Current_Exit;
}
void Current_Exit(object sender, ExitEventArgs e)
{
Telnet.Close();
}
public static void StartDemo(string workplace)
{
Task.Run(() =>
{
Current
.Dispatcher.BeginInvoke(new Action
(() =>
{
MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace), Mode.Demo.ToString());
}));
});
}
public static void Start(string workplace)
{
Task.Run(() =>
{
Current
.Dispatcher.BeginInvoke(new Action
(() =>
{
try
{
MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace), CurrentMode.ToString());
}
catch(Exception)
{
MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace));
}
switch (CurrentMode)
{
case Mode.Study:
TutorialWindow
= new TutorialWindow
();
TutorialWindow.Topmost = true;
TutorialWindow.Show();
break;
case Mode.Exam:
TutorialWindow
= new ExamWindow
();
TutorialWindow.Topmost = true;
TutorialWindow.Show();
break;
}
}));
});
}
public static void PrepareControls()
{
if (ActiveTutorial != null && ActiveTutorial.PrepareControls != null)
{
foreach (var control in ActiveTutorial.PrepareControls)
{
CheckBox chkBox = FindChild(Current.MainWindow, control) as CheckBox;
if (chkBox != null)
{
chkBox.IsChecked = !chkBox.IsChecked;
}
else
{
try
{ //TODO: програмное нажатие кнопки
(App.MainFrame.Content as BaseFrame).prepareElement(control);
}
catch (Exception) { }
}
}
}
}
public static void Stop()
{
if (TutorialWindow != null)
TutorialWindow.Close();
Telnet.Close();
Current
.Dispatcher.BeginInvoke(new Action
(() =>
{
if (App.Current.MainWindow.WindowStyle == WindowStyle.None)
{
App.Current.MainWindow.WindowStyle = WindowStyle.SingleBorderWindow;
App.Current.MainWindow.ResizeMode = ResizeMode.CanResize;
App.Current.MainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
App.Current.MainWindow.WindowState = WindowState.Normal;
App.Current.MainWindow.Hide();
App.Current.MainWindow.Show();
}
MainFrame
.Source = new Uri
("MenuPage.xaml", UriKind
.RelativeOrAbsolute);
}));
foreach (var u in Units)
u.Dispose();
Units.Clear();
}
public static bool BroadcastMessage(string Message, bool FromTelnet)
{
if (Message != null)
{
bool MessageAccepted = false;
foreach (Unit unit in Units)
{
if (unit.RecieveMessage(Message))
{
MessageAccepted = true;
}
}
if (Telnet.IsConnected && !FromTelnet)
{
Telnet.Send(Message);
}
if (CurrentMode == Mode.Exam || CurrentMode == Mode.Study)
{
if (ActiveTutorial.CurrentStep != null && ActiveTutorial.CurrentStep.Command != null)
{
if (Message.Contains(ActiveTutorial.CurrentStep.Command))
{
if (ActiveTutorial.CurrentStep.Conditions != null && ActiveTutorial.CurrentStep.Conditions.Count > 0)
{
foreach (var cond in ActiveTutorial.CurrentStep.Conditions)
{
object unit = App.Units.FirstOrDefault(u => u.Name == cond.UnitName);
if (unit != null)
{
string[] path = cond.Path.Split('/');
PropertyInfo propertyInfo = null;
object property = unit;
Type type = unit.GetType();
foreach (var segment in path)
{
if (segment[0] == '[')
{
if (!segment.Contains('='))
{
int index;
int.TryParse(segment.Substring(1, segment.Length - 2), out index);
int i = 0;
foreach (var element in property as IEnumerable)
{
if (index == i)
{
property = element;
break;
}
i++;
}
}
else
{
int eqSignPos = segment.IndexOf('=');
string key = segment.Substring(1, eqSignPos - 1);
string value = segment.Substring(eqSignPos + 1, segment.Length - eqSignPos - 2);
foreach (var element in property as IEnumerable)
{
PropertyInfo elemInfo = element.GetType().GetProperty(key);
if (elemInfo.GetValue(element).ToString() == value)
{
property = element;
break;
}
}
}
}
else
{
propertyInfo = type.GetProperty(segment);
if (propertyInfo != null)
property = propertyInfo.GetValue(property);
}
if (property == null)
break;
type = property.GetType();
}
if (cond.Tolerance != 0)
{
if (Math.Abs(double.Parse(property.ToString()) - double.Parse(cond.Value)) <= cond.Tolerance)
cond.IsMet = true;
}
else
{
if (property != null)
{
switch (type.Name)
{
case "bool":
if (((bool)property == true && cond.Value == "True") ||
((bool)property == false && cond.Value == "False"))
cond.IsMet = true;
break;
default:
if (property.ToString() == (cond.Value))
cond.IsMet = true;
break;
}
}
}
}
}
if (ActiveTutorial.CurrentStep.Conditions.Where(c => c.IsMet).Count() == ActiveTutorial.CurrentStep.Conditions.Count())
TutorialStepCompleted();
}
else TutorialStepCompleted();
}
}
}
return MessageAccepted;
}
else
{
return false;
}
}
private static void TutorialStepCompleted()
{
ActiveTutorial.NextStep();
}
public static void Connect(string Server, string Client, string Workplace)
{
_client = Client;
_workplace = Workplace;
Telnet.Connected += Telnet_Connected;
Telnet.Connect(Server, 27027);
}
static void Telnet_Connected(object sender, EventArgs e)
{
Telnet.Send(String.Format("Connect {0} {1}", _client, _workplace));
App
.Current.Dispatcher.BeginInvoke(new Action
(() => Start
(_workplace
)));
}
public static void StartServer(int Port)
{
Telnet.StartServer(Port);
}
static void Telnet_MessageRecieved(object sender, string e)
{
if (e != null)
{
String[] Comms = e.Split('\n');
List
<String> Commands
= new List
<string>(Comms
);
Commands.Sort();
foreach (string command in Commands)
{
if (command != String.Empty)
{
String[] Message = command.Split(' ');
switch (Message[0])
{
case "Connect":
//TODO
if (Checker == true && Telnet.ClientSocket == null)
{
string[] MessageSplitted = {""};
MessageSplitted
= Message
[2].Split(new string[] { "Big" }, StringSplitOptions
.None);
if (MessageSplitted.Length < 2) {
MessageSplitted
= Message
[2].Split(new string[] { "Small" }, StringSplitOptions
.None);
}
if (Message[2].Contains("OperatorPage"))
{
int op_counter = 0;
if (MainFrame.Content.ToString().Contains("OperatorPage"))
op_counter += 1;
foreach (Client imposter in Clients)
if (imposter.Workspace.Contains("OperatorPage"))
op_counter += 1;
if (op_counter < 2)
Clients
.Add(new Client
(Message
[1], Message
[2]));
else
Telnet.Send(String.Format("You are impostor {0}", Message[1]));
}
else
{
if(!MainFrame.Content.ToString().Contains(MessageSplitted[1]))
{
foreach (Client imposter in Clients)
if (imposter.Workspace == Message[2])
{
Telnet.Send(String.Format("You are impostor {0}", Message[1]));
break;
}
Clients
.Add(new Client
(Message
[1], Message
[2]));
}
else
Telnet.Send(String.Format("You are impostor {0}", Message[1]));
}
}
else
Clients
.Add(new Client
(Message
[1], Message
[2]));
break;
case "You":
if (Message[3] == Telnet.ClientSocket.LocalEndPoint.ToString().Split(':')[0])
{
App.Stop();
MessageBox.Show("Server closed connection", "Closed", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
foreach (Client impostor in Clients)
{
if (Message[3] == impostor.IPAddress)
{
Clients.Remove(impostor);
}
}
}
break;
default:
if(command != "CommonInfoArrayNotif 53 0")
BroadcastMessage(command, true);
break;
}
}
}
}
}
public static DependencyObject FindChild(DependencyObject parent, string name)
{
if (parent == null || string.IsNullOrEmpty(name))
return null;
if (parent
is FrameworkElement
&& (parent
as FrameworkElement
).Name == name
)
return parent;
DependencyObject result = null;
if (parent
is FrameworkElement
)
(parent as FrameworkElement).ApplyTemplate();
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
result = FindChild(child, name);
if (result != null)
break;
}
return result;
}
public static double GetAngle(double x, double y)
{
if (x == 0)
{
if (y > 0)
return 180;
else
return 0;
}
else
{
if (x > 0 && y < 0)
return 90 - Math.Atan(Math.Abs(y) / x) * 180 / Math.PI;
if (x > 0 && y >= 0)
return Math.Atan(y / x) * 180 / Math.PI + 90;
if (x < 0 && y >= 0)
return -Math.Atan(y / Math.Abs(x)) * 180 / Math.PI + 270;
if (x < 0 && y < 0)
return Math.Atan(Math.Abs(y) / Math.Abs(x)) * 180 / Math.PI + 270;
}
return 0;
}
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs
(propertyName
));
}
}
#endregion
}
}