//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.App
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;
using System.CodeDom;
using System.IO;
using System.Xml;
using Microsoft.Xna;
using Microsoft.Xna.Framework;
using DarkWynter.Stream;
using DarkWynter.Engine.Globals;
using DarkWynter.Engine.Init;
using DarkWynter.Engine.Utilities;
using DarkWynter.Engine.EventControl;
using DarkWynter.Game;
using DarkWynter.Engine.GameObjects;
using DarkWynter.App.Surveys;
using DarkWynter.App.ChallengeSet;
using System.Threading;
using CSTextEditor;
//using CSTextEditor;
#endregion
///
/// The compiler form
///
public partial class CompilerControl : UserControl
{
public static CompilerControl compilerControl;
public static List challengeList;
public static MenuStrip menuStripPointer;
public static ToolStripMenuItem refreshPointer;
CompilerResults compilerResults;
PrettyCompilerControl prettyCompilerControl;
public static RichTextBox richTextBox_CodeWindow;
int unsuccessfulCompiles = 0;
public static string customErrorMessage;
public static string studentCode;
string cleanedStudentCode;
bool docked = true;
public delegate void Output_EventHandler(string message);
///
/// CompilerControl constructor
///
public CompilerControl()
{
InitializeComponent();
this.Dock = DockStyle.Fill;
LoadChallenges();
//menuStrip1.Hide();
menuStripPointer = menuStrip1;
CompilerControl.richTextBox_CodeWindow = this.codeTextBox;
Engine.DarkWynterEngine.onLevelChange += new DarkWynter.Engine.DarkWynterEngine.OnLevelChange(this.Load_OnLevelChange);
compilerControl = this;
numberLabel.Font = new Font(codeTextBox.Font.FontFamily, codeTextBox.Font.Size - 0.0f);
}
public void Load_OnLevelChange(EventArgs e)
{
Statics_Engine.GameSettings.isProblemFinished = true;
resetText();
}
///
/// Loads the challenges from XML
///
private void LoadChallenges()
{
#region Challenges
// Create Challenge List
challengeList = new List();
for (int i = 0; i < XML.ChallengeNodes.Count; i++)
{
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 0)
{
challengeList.Add(new Challenge0(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 1)
{
challengeList.Add(new Challenge1(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 2)
{
challengeList.Add(new Challenge2(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 3)
{
challengeList.Add(new Challenge3(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 4)
{
challengeList.Add(new Challenge4(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 5)
{
challengeList.Add(new Challenge5(XML.ChallengeNodes[i]));
}
if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 6)
{
challengeList.Add(new Challenge6(XML.ChallengeNodes[i]));
}
}
// Init first problem
Statics_Engine.GameSettings.currentChallengeNumber = DarkWynter.Engine.Globals.Statics_Engine.levelIndex;
// Load the first problem
codeTextBox.Text =
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding();
// Load the first instructions
InstructionControl.dialogTextBoxPointer.Text +=
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].challengeDialogue[challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter] + "\r\n";
#endregion
}
#region Compile and Run the code
public string CompileCodeWithOutput()
{
CompileCode();
return outputTextBox.Text;
}
///
/// Compiles the code in the codeTextBox.Text field
///
public void CompileCode()
{
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Student hit compiler button [End Button Message]");
Logging.G2LLogList.Add("\r\n[Student Code] - \r\n");
Logging.G2LLogList.Add(cleanedStudentCode + "\r\n[End Student Code]\r\n");
compilerResults = DarkWynter.Engine.Compiler.CSharpCompiler.CompileCode(studentCode);
// If _does_not_ compile
if (compilerResults.Errors.Count > 0)
{
// Display compilation errors.
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Errors building {0} into {1}\n\n",
studentCode, compilerResults.PathToAssembly);
foreach (CompilerError ce in compilerResults.Errors)
{
sb.Append(ce.ToString());
sb.Append("\n");
}
unsuccessfulCompiles++;
GameEventHandler.CurrentGameConditions.triggerSanity = 11;
outputTextBox.Text = sb.ToString();
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Error Message] There were errors in the code [End Error Message] ");
Logging.G2LLogList.Add(sb.ToString());
Logging.G2LLogList.Add(" [Record Message] This is the " + unsuccessfulCompiles + " attempt at this problem. [End Record Message] ");
}
if (compilerResults.Errors.Count == 0)
{
outputTextBox.Text = "Compile Successful\n";
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Success Message] There were no errors in the code [End Success Message] ");
}
// Update Pretty Compiler Output box
//OutputChanged(outputTextBox.Text);
}
///
/// Runs the compiled code
///
///
///
private void runToolStripMenuItem_Click(object sender, EventArgs e)
{
RunCode();
}
///
/// Runs the Code, after compilation, in the codeTextBoc.Text field
///
public void RunCode()
{
// If it hasn't been compiled, just have them compile it
if (compilerResults == null)
{
outputTextBox.Text = "You must compile before you can run!";
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Error Message] Student tried to run without compiling first. [End Error Message]");
return;
}
// If compiles, validate output
if (compilerResults.Errors.Count == 0)
{
StringWriter stringWriter = new StringWriter();
Console.SetOut(stringWriter);
// Execute user code
DarkWynter.Engine.Compiler.CSharpCompiler.Execute(compilerResults.CompiledAssembly, "Test", "MyFunction", null);
// List output in compiler feedback box
try
{
outputTextBox.Text += stringWriter.ToString();
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Compiler output] - ");
Logging.G2LLogList.Add(stringWriter.ToString() + "[End Compiler output]\r\n");
// Execute instructor evaluation and feedback function
if (challengeList[Statics_Engine.GameSettings.currentChallengeNumber].ValidateStudentCode(studentCode, stringWriter.ToString()))
{
if (Statics_Engine.GameSettings.isProblemFinished == false)
{
// Set the statics for the HUD to use to run the actual visualization while the code runs for the student
// Statics_Engine.GameSettings.ParsesandCompilesCode = studentCode;
// If correct, call the vis code
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].RunVizualization(stringWriter.ToString());
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Success Message] Bridge " +
Statics_Engine.GameSettings.currentChallengeNumber + " built successfully. [End Success Message]");
// Ensure Current Prob does not go out of bounds
if (Statics_Engine.GameSettings.currentChallengeNumber < challengeList.Count - 1)
{
// Finish the vis and don't run it again
Statics_Engine.GameSettings.isProblemFinished = true;
//HERE
//Statics_Engine.GameSettings.currentChallengeNumber++;
}
}
}
// write the custom error message to the screen and to the log
else
outputTextBox.Text = customErrorMessage;
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Custom Error Message] " + customErrorMessage + " [End Custom Error Message]");
}
catch (NullReferenceException x)
{
outputTextBox.Text = x.ToString();
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Compiler output] - ");
// Logging.G2LLogList.Add(runOnWhile + "[End Compiler output]\r\n");
}
// Move the scroller down
ScrolltoText();
stringWriter.Close();
//resetText();
}
// Update Pretty Compiler Output box
//OutputChanged(outputTextBox.Text);
}
#endregion
#region Buttons, buttons, and more buttons
///
/// Open the form, deactivates Engine controls, resize the gameWindow, handle resetText() trigger
///
///
///
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Compiler panels opened [End Button Message]");
Logging.G2LLogList.Add("\r\n[Game Message] Student is on problem number " +
Statics_Engine.GameSettings.currentChallengeNumber);
Logging.G2LLogList.Add("Student is on island number " +
Statics_Engine.GameSettings.currentChallengeNumber + " [End Game Message] \r\n");
Engine.DarkWynterEngine.Deactivate();
//compilerPanel.Show();
//dialogueGroupPanel.Show();
// getTMLoc.Show();
//getTMLoc.Enabled = true;
if (Statics_Engine.PlayerSettings.doResetText == true)
{
resetText();
}
//int GameWindowWidth = 620;
//int GameWindowHeight = 500;
//GameForm.dwGameControl.Location = new System.Drawing.Point(400, 55);
//GameForm.dwGameControl.Size = new System.Drawing.Size(GameWindowWidth, GameWindowHeight);
// Set the viewport
Microsoft.Xna.Framework.Graphics.Viewport viewport = new Microsoft.Xna.Framework.Graphics.Viewport();
//viewport.X = GameForm.dwGameControl.Location.X;
//viewport.Y = GameForm.dwGameControl.Location.Y;
//viewport.Width = GameForm.dwGameControl.Size.Width;
//viewport.Height = GameForm.dwGameControl.Size.Height;
viewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth;
viewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth;
Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport = viewport;
}
///
/// Reactivates Engine controls, resets gameWindow
///
///
///
private void closeCompilerToolStripMenuItem1_Click(object sender, EventArgs e)
{
Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Compiler panels closed [End Button Message] ");
Engine.DarkWynterEngine.Activate();
//compilerPanel.Hide();
//dialogueGroupPanel.Hide();
//compileButton.Hide();
//runButton.Hide();
// getTMLoc.Hide();
// getTMLoc.Enabled = false;
//GameForm.dwGameControl.Location = new System.Drawing.Point(0, 25);
//GameForm.dwGameControl.Size = new System.Drawing.Size(1024, 743);
// Set the viewport
Microsoft.Xna.Framework.Graphics.Viewport viewport = new Microsoft.Xna.Framework.Graphics.Viewport();
//viewport.X = GameForm.dwGameControl.Location.X;
//viewport.Y = GameForm.dwGameControl.Location.Y;
//viewport.Width = GameForm.dwGameControl.Size.Width;
//viewport.Height = GameForm.dwGameControl.Size.Height;
viewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth;
viewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth;
Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport = viewport;
}
///
/// Will save out to a text file when I finish it
///
///
///
private void saveButton_Click(object sender, EventArgs e)
{
// save the code out
String name = "problem" + Statics_Engine.GameSettings.currentChallengeNumber + ".txt";
string logFile = "../../../__Game/Compiler/Logs/" + name;
StreamWriter myFile = null;
FileStream fileStream = File.Open(logFile, FileMode.CreateNew, FileAccess.Write);
myFile = new StreamWriter(fileStream);
myFile.WriteLine(DateTime.Now);
myFile.Write(codeTextBox.Text);
//myFile.Write(compilerExternalForm.textEditorControl1.Text);
myFile.Close();
}
///
/// Activate Compiler
///
///
///
private void compileToolStripMenuItem_Click(object sender, EventArgs e)
{
// Compile student code
studentCode = codeTextBox.Text;
cleanedStudentCode = studentCode.Trim();
cleanedStudentCode = studentCode.Replace('\n', ' ');
CompileCode();
}
///
/// Refreshes to the next code set
///
///
///
public void refreshToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Statics_Engine.GameSettings.isProblemFinished == true)
{
//HERE
Statics_Engine.GameSettings.currentChallengeNumber++;
resetText();
resetText();
}
else
resetText();
}
#endregion
#region Helper methods
// autoscoll boxNumber keeps track of which one we are changing
public void ScrolltoText()
{
outputTextBox.SelectionStart = outputTextBox.Text.Length;
outputTextBox.ScrollToCaret();
outputTextBox.Select();
}
///
/// Resets all the text boxes back to initial state
///
public void resetText()
{
// Reset dialog counter in problem
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter = 0;
// Clear boxes
InstructionControl.dialogTextBoxPointer.Text = "";
outputTextBox.Text = "";
codeTextBox.Text = "";
// Load the problem
codeTextBox.Text =
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding();
// External Form
//compilerExternalForm.textEditorControl1.Text =
//challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding();
// Load the first instructions
InstructionControl.dialogTextBoxPointer.Text +=
challengeList[Statics_Engine.GameSettings.currentChallengeNumber]
.challengeDialogue[challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter] + "\r\n";
Statics_Engine.GameSettings.isProblemFinished = false;
}
private void updateNumberLabel()
{
//we get index of first visible char and number of first visible line
System.Drawing.Point pos = new System.Drawing.Point(0, 0);
int firstIndex = codeTextBox.GetCharIndexFromPosition(pos);
int firstLine = codeTextBox.GetLineFromCharIndex(firstIndex);
//now we get index of last visible char and number of last visible line
pos.X = ClientRectangle.Width;
pos.Y = ClientRectangle.Height;
int lastIndex = codeTextBox.GetCharIndexFromPosition(pos);
int lastLine = codeTextBox.GetLineFromCharIndex(lastIndex);
//this is point position of last visible char, we'll use its Y value for calculating numberLabel size
pos = codeTextBox.GetPositionFromCharIndex(lastIndex);
//finally, renumber label
numberLabel.Text = "";
for (int i = firstLine; i <= lastLine + 1; i++)
{
numberLabel.Text += i + 1 + "\n";
}
}
private void codeTextBox_TextChanged(object sender, EventArgs e)
{
updateNumberLabel();
}
private void codeTextBox_VScroll(object sender, EventArgs e)
{
//move location of numberLabel for amount of pixels caused by scrollbar
int d = codeTextBox.GetPositionFromCharIndex(0).Y % (codeTextBox.Font.Height + 1);
numberLabel.Location = new System.Drawing.Point(0, d);
updateNumberLabel();
}
private void codeTextBox_Resize(object sender, EventArgs e)
{
codeTextBox_VScroll(null, null);
}
private void richTextBox1_FontChanged(object sender, EventArgs e)
{
updateNumberLabel();
codeTextBox_VScroll(null, null);
}
#endregion
#region External Compiler
private void cSCompilerToolStripMenuItem_Click(object sender, EventArgs e)
{
// Form thread
Thread t = new Thread(new ThreadStart(compilerForm));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
//[MTAThread]
///
///
///
private void compilerForm()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
prettyCompilerControl = new PrettyCompilerControl();
//prettyCompilerControl.compileToolStripMenuItem.Click += new System.EventHandler(this.compileToolStripMenuItem_Click);
//prettyCompilerControl.debugToolStripMenuItem.Click += new System.EventHandler(this.runToolStripMenuItem_Click);
prettyCompilerControl.textEditorControl1.Text =
challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding();
Application.Run(prettyCompilerControl);
//compilerForm.MinimizeBox = false;
//compilerForm.MaximizeBox = false;
//compilerForm.FormBorderStyle = FormBorderStyle.Sizable;
//compilerForm.Show();
}
private void undockToolStripMenuItem_Click(object sender, EventArgs e)
{
if (docked)
{
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Controls.Clear();
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Controls.Add(this);
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Name = "CompilerForm";
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Text = "Compiler Form";
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.WindowState = FormWindowState.Maximized;
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.ControlBox = false;
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.MaximizeBox = false;
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.MinimizeBox = false;
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.ResumeLayout(false);
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Show();
UCADInterfaceControl._UCAD_Inteface.LeftPanelCollapse();
undockToolStripMenuItem.Text = "Dock";
docked = false;
}
else
{
UCADInterfaceControl._UCAD_Inteface.UCAD_Left_Panel.Controls.Clear();
UCADInterfaceControl._UCAD_Inteface.UCAD_Left_Panel.Controls.Add(this);
UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Hide();
UCADInterfaceControl._UCAD_Inteface.LeftPanelExpand();
//UCADInterfaceControl._UCAD_Self.UCAD_Left_SplitContainer.Panel1Collapsed = true;
undockToolStripMenuItem.Text = "Undock";
docked = true;
}
}
/////
///// The main entry point for the application.
/////
//[STAThread]
//static void RunCompilerForm()
//{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new MainForm());
//}
#endregion
}
}