using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;
using Microsoft.DirectX.DirectSound;
using AdaptiveResponse;
using WaveLib;

namespace HearingAidLab
{
	/// <summary>
	/// BIG ASS SUMMARY FOR STAR
	/// In an effort to be versatile, we've got quite a bit going on in Star.
	/// 
	/// </summary>
	public class Star : System.Windows.Forms.Form
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.TextBox txtPrimary;
		private System.Windows.Forms.TextBox txtWrong;
		private System.Windows.Forms.TextBox txtRight;
		private System.Windows.Forms.TextBox txtCurrent;
		private System.Windows.Forms.TextBox txtTotal;
		private System.Windows.Forms.TextBox txtLevel;
		private System.Windows.Forms.TextBox txtSecondary;
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.TextBox txtTime;
		private System.Windows.Forms.Button btnPause;

		public StreamWriter output;
		public Form1 mainmenu;
		public System.Windows.Forms.Timer timer;
		public System.Windows.Forms.Timer timer2;
		public System.Windows.Forms.Timer timerCatch;
		public System.Windows.Forms.Timer timer3;

		private StarGame.GameForm game;
		private Run Primary;
		private Run Secondary;
//		private string strResponse;
		private ArrayList listStats;

		private bool bFirst = true;
		private bool bSecondary = false;
		private bool bButtons = true;
		private bool Paused = false;
		private bool bBandwidth = false;
		private bool bGlobalDone = false;
		private int nR = 0;
		private int nAdaptType = 0;
		private string strButton = string.Empty;

		private int nCompleted=0;
		private int nRight=0;
		private int nWrong=0;
		private int nDelay=1;
		private int nCount=0;
		private int nCorrect=0;
		private int nReversals = 0;
				
		private DateTime dtStarted;
		public FileInfo outfile;
				
		private AR PrimaryAR;	//Primary Stim AR
		private AR SecondaryAR; // Secondary Stim AR
		private System.Windows.Forms.ListView listView1;
		private System.Windows.Forms.ListView listView2;
		private ListViewColumnSorter lvwColumnSorter;
		private ListViewColumnSorter lvwColumnSorter2;
		private System.Windows.Forms.Button btnSummary;
		private System.Windows.Forms.TextBox txtStdErr;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.Button btnReset;
		private System.Windows.Forms.Button btnSkip;
		public WaveLib.WavePlayer player = new WaveLib.WavePlayer();
		private Stim Masker = null;
		private bool Summary = true;
		private ArrayList TwoWayRandom;
		private bool bTwoWay = false;
		private bool bWaiting = false;
		private bool bNewSecondary = false;

		//interval mode
		private bool bInterval = false;
		private ArrayList IntervalList;
		private Timer ITimerOn;
		private Timer ITimerSpace;
		private System.Windows.Forms.TextBox txtMFile;
		private System.Windows.Forms.Label label10;
		public StreamWriter iwriter = null;
		private System.Windows.Forms.Label lblKey;
		private System.Windows.Forms.Label lblCal;
		private System.Windows.Forms.StatusBar statusBar1;
		private System.Windows.Forms.StatusBarPanel sbStatus;
		private string strSec = string.Empty; //holds names of secondary stimuli for writing to results file

		private int iNumButton=0; // keeps count of num of buttons that are used for response eg. A,B but not Repeat
		public Star(bool bSingleScreen)
		{
			//
			// Required for Windows Form Designer support
			//
			/*if(bSingleScreen==false)
			{
				this.Location = new Point(100,100);
				this.WindowState = FormWindowState.Normal;
			}
			else
			{
				this.Location = new Point(100,100);
				this.WindowState = FormWindowState.Normal;
			}*/
			InitializeComponent();

			this.Closing+=new CancelEventHandler(Star_Closing);
			if(player.Open()==false)
			{
				MessageBox.Show(this,"Unable to open sound card!","Audio Error",MessageBoxButtons.OK,MessageBoxIcon.Stop);
				return;
			}
			lvwColumnSorter = new ListViewColumnSorter();
			lvwColumnSorter2 = new ListViewColumnSorter();
			listView1.ListViewItemSorter = lvwColumnSorter;
			listView2.ListViewItemSorter = lvwColumnSorter2;
			listView1.ColumnClick += new ColumnClickEventHandler(listView1_ColumnClick);
			listView2.ColumnClick += new ColumnClickEventHandler(listView2_ColumnClick);
			Primary = new Run();
			Secondary = new Run();
			PrimaryAR = new AR();
			SecondaryAR = new AR();
			
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Star));
			this.label1 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.label5 = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.label7 = new System.Windows.Forms.Label();
			this.txtPrimary = new System.Windows.Forms.TextBox();
			this.txtWrong = new System.Windows.Forms.TextBox();
			this.txtRight = new System.Windows.Forms.TextBox();
			this.txtCurrent = new System.Windows.Forms.TextBox();
			this.txtTotal = new System.Windows.Forms.TextBox();
			this.txtLevel = new System.Windows.Forms.TextBox();
			this.txtSecondary = new System.Windows.Forms.TextBox();
			this.label8 = new System.Windows.Forms.Label();
			this.txtTime = new System.Windows.Forms.TextBox();
			this.btnPause = new System.Windows.Forms.Button();
			this.listView1 = new System.Windows.Forms.ListView();
			this.listView2 = new System.Windows.Forms.ListView();
			this.btnSummary = new System.Windows.Forms.Button();
			this.txtStdErr = new System.Windows.Forms.TextBox();
			this.label9 = new System.Windows.Forms.Label();
			this.btnReset = new System.Windows.Forms.Button();
			this.btnSkip = new System.Windows.Forms.Button();
			this.txtMFile = new System.Windows.Forms.TextBox();
			this.label10 = new System.Windows.Forms.Label();
			this.lblKey = new System.Windows.Forms.Label();
			this.lblCal = new System.Windows.Forms.Label();
			this.statusBar1 = new System.Windows.Forms.StatusBar();
			this.sbStatus = new System.Windows.Forms.StatusBarPanel();
			((System.ComponentModel.ISupportInitialize)(this.sbStatus)).BeginInit();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(8, 8);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(160, 23);
			this.label1.TabIndex = 0;
			this.label1.Text = "Current Primary Stimulus:";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(8, 32);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(160, 23);
			this.label2.TabIndex = 1;
			this.label2.Text = "Current Secondary Stimulus:";
			this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(8, 56);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(160, 23);
			this.label3.TabIndex = 2;
			this.label3.Text = "Primary Stimulus Pres. Level:";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(8, 104);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(160, 23);
			this.label4.TabIndex = 3;
			this.label4.Text = "Total Presentations:";
			this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label5
			// 
			this.label5.Location = new System.Drawing.Point(8, 128);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(160, 23);
			this.label5.TabIndex = 4;
			this.label5.Text = "Completed:";
			this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label6
			// 
			this.label6.Location = new System.Drawing.Point(8, 152);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(160, 23);
			this.label6.TabIndex = 5;
			this.label6.Text = "Right:";
			this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label7
			// 
			this.label7.Location = new System.Drawing.Point(8, 176);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(160, 23);
			this.label7.TabIndex = 6;
			this.label7.Text = "Wrong:";
			this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// txtPrimary
			// 
			this.txtPrimary.Location = new System.Drawing.Point(168, 9);
			this.txtPrimary.Name = "txtPrimary";
			this.txtPrimary.ReadOnly = true;
			this.txtPrimary.Size = new System.Drawing.Size(192, 20);
			this.txtPrimary.TabIndex = 7;
			this.txtPrimary.Text = "";
			// 
			// txtWrong
			// 
			this.txtWrong.Location = new System.Drawing.Point(168, 177);
			this.txtWrong.Name = "txtWrong";
			this.txtWrong.ReadOnly = true;
			this.txtWrong.Size = new System.Drawing.Size(192, 20);
			this.txtWrong.TabIndex = 8;
			this.txtWrong.Text = "";
			// 
			// txtRight
			// 
			this.txtRight.Location = new System.Drawing.Point(168, 153);
			this.txtRight.Name = "txtRight";
			this.txtRight.ReadOnly = true;
			this.txtRight.Size = new System.Drawing.Size(192, 20);
			this.txtRight.TabIndex = 9;
			this.txtRight.Text = "";
			// 
			// txtCurrent
			// 
			this.txtCurrent.Location = new System.Drawing.Point(168, 129);
			this.txtCurrent.Name = "txtCurrent";
			this.txtCurrent.ReadOnly = true;
			this.txtCurrent.Size = new System.Drawing.Size(192, 20);
			this.txtCurrent.TabIndex = 10;
			this.txtCurrent.Text = "";
			// 
			// txtTotal
			// 
			this.txtTotal.Location = new System.Drawing.Point(168, 105);
			this.txtTotal.Name = "txtTotal";
			this.txtTotal.ReadOnly = true;
			this.txtTotal.Size = new System.Drawing.Size(192, 20);
			this.txtTotal.TabIndex = 11;
			this.txtTotal.Text = "";
			// 
			// txtLevel
			// 
			this.txtLevel.Location = new System.Drawing.Point(168, 57);
			this.txtLevel.Name = "txtLevel";
			this.txtLevel.ReadOnly = true;
			this.txtLevel.Size = new System.Drawing.Size(192, 20);
			this.txtLevel.TabIndex = 12;
			this.txtLevel.Text = "";
			// 
			// txtSecondary
			// 
			this.txtSecondary.Location = new System.Drawing.Point(168, 33);
			this.txtSecondary.Name = "txtSecondary";
			this.txtSecondary.ReadOnly = true;
			this.txtSecondary.Size = new System.Drawing.Size(192, 20);
			this.txtSecondary.TabIndex = 13;
			this.txtSecondary.Text = "";
			// 
			// label8
			// 
			this.label8.Location = new System.Drawing.Point(8, 200);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(160, 23);
			this.label8.TabIndex = 14;
			this.label8.Text = "Elapsed Time:";
			this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// txtTime
			// 
			this.txtTime.Location = new System.Drawing.Point(168, 201);
			this.txtTime.Name = "txtTime";
			this.txtTime.ReadOnly = true;
			this.txtTime.Size = new System.Drawing.Size(192, 20);
			this.txtTime.TabIndex = 15;
			this.txtTime.Text = "";
			// 
			// btnPause
			// 
			this.btnPause.Location = new System.Drawing.Point(192, 480);
			this.btnPause.Name = "btnPause";
			this.btnPause.TabIndex = 16;
			this.btnPause.Text = "Pause";
			this.btnPause.Visible = false;
			this.btnPause.Click += new System.EventHandler(this.btnPause_Click);
			// 
			// listView1
			// 
			this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.listView1.FullRowSelect = true;
			this.listView1.Location = new System.Drawing.Point(360, 8);
			this.listView1.Name = "listView1";
			this.listView1.Size = new System.Drawing.Size(424, 256);
			this.listView1.TabIndex = 17;
			this.listView1.View = System.Windows.Forms.View.Details;
			// 
			// listView2
			// 
			this.listView2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.listView2.FullRowSelect = true;
			this.listView2.Location = new System.Drawing.Point(360, 272);
			this.listView2.Name = "listView2";
			this.listView2.Size = new System.Drawing.Size(424, 256);
			this.listView2.TabIndex = 18;
			this.listView2.View = System.Windows.Forms.View.Details;
			// 
			// btnSummary
			// 
			this.btnSummary.Location = new System.Drawing.Point(160, 336);
			this.btnSummary.Name = "btnSummary";
			this.btnSummary.Size = new System.Drawing.Size(104, 23);
			this.btnSummary.TabIndex = 19;
			this.btnSummary.Text = "Write Summary";
			this.btnSummary.Click += new System.EventHandler(this.btnSummary_Click);
			// 
			// txtStdErr
			// 
			this.txtStdErr.Location = new System.Drawing.Point(168, 81);
			this.txtStdErr.Name = "txtStdErr";
			this.txtStdErr.ReadOnly = true;
			this.txtStdErr.Size = new System.Drawing.Size(192, 20);
			this.txtStdErr.TabIndex = 21;
			this.txtStdErr.Text = "";
			// 
			// label9
			// 
			this.label9.Location = new System.Drawing.Point(8, 80);
			this.label9.Name = "label9";
			this.label9.Size = new System.Drawing.Size(160, 23);
			this.label9.TabIndex = 20;
			this.label9.Text = "StdErr:";
			this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// btnReset
			// 
			this.btnReset.Location = new System.Drawing.Point(192, 408);
			this.btnReset.Name = "btnReset";
			this.btnReset.TabIndex = 22;
			this.btnReset.Text = "Reset";
			this.btnReset.Visible = false;
			this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
			// 
			// btnSkip
			// 
			this.btnSkip.Location = new System.Drawing.Point(192, 440);
			this.btnSkip.Name = "btnSkip";
			this.btnSkip.TabIndex = 23;
			this.btnSkip.Text = "Skip";
			this.btnSkip.Visible = false;
			this.btnSkip.Click += new System.EventHandler(this.btnSkip_Click);
			// 
			// txtMFile
			// 
			this.txtMFile.Location = new System.Drawing.Point(168, 225);
			this.txtMFile.Name = "txtMFile";
			this.txtMFile.ReadOnly = true;
			this.txtMFile.Size = new System.Drawing.Size(192, 20);
			this.txtMFile.TabIndex = 25;
			this.txtMFile.Text = "";
			// 
			// label10
			// 
			this.label10.Location = new System.Drawing.Point(8, 224);
			this.label10.Name = "label10";
			this.label10.Size = new System.Drawing.Size(160, 23);
			this.label10.TabIndex = 24;
			this.label10.Text = "Frequency Shaping File:";
			this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblKey
			// 
			this.lblKey.Location = new System.Drawing.Point(8, 256);
			this.lblKey.Name = "lblKey";
			this.lblKey.Size = new System.Drawing.Size(100, 112);
			this.lblKey.TabIndex = 26;
			this.lblKey.Text = "label11";
			// 
			// lblCal
			// 
			this.lblCal.Location = new System.Drawing.Point(8, 368);
			this.lblCal.Name = "lblCal";
			this.lblCal.Size = new System.Drawing.Size(264, 23);
			this.lblCal.TabIndex = 27;
			this.lblCal.Text = "label11";
			// 
			// statusBar1
			// 
			this.statusBar1.Location = new System.Drawing.Point(0, 544);
			this.statusBar1.Name = "statusBar1";
			this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
																						  this.sbStatus});
			this.statusBar1.ShowPanels = true;
			this.statusBar1.Size = new System.Drawing.Size(792, 22);
			this.statusBar1.TabIndex = 28;
			this.statusBar1.Text = "statusBar1";
			// 
			// sbStatus
			// 
			this.sbStatus.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Contents;
			this.sbStatus.Text = "Status:";
			this.sbStatus.Width = 49;
			// 
			// Star
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(792, 566);
			this.Controls.Add(this.statusBar1);
			this.Controls.Add(this.txtMFile);
			this.Controls.Add(this.txtStdErr);
			this.Controls.Add(this.txtTime);
			this.Controls.Add(this.txtSecondary);
			this.Controls.Add(this.txtLevel);
			this.Controls.Add(this.txtTotal);
			this.Controls.Add(this.txtCurrent);
			this.Controls.Add(this.txtRight);
			this.Controls.Add(this.txtWrong);
			this.Controls.Add(this.txtPrimary);
			this.Controls.Add(this.lblCal);
			this.Controls.Add(this.lblKey);
			this.Controls.Add(this.label10);
			this.Controls.Add(this.btnSkip);
			this.Controls.Add(this.btnReset);
			this.Controls.Add(this.label9);
			this.Controls.Add(this.btnSummary);
			this.Controls.Add(this.listView2);
			this.Controls.Add(this.listView1);
			this.Controls.Add(this.btnPause);
			this.Controls.Add(this.label8);
			this.Controls.Add(this.label7);
			this.Controls.Add(this.label6);
			this.Controls.Add(this.label5);
			this.Controls.Add(this.label4);
			this.Controls.Add(this.label3);
			this.Controls.Add(this.label2);
			this.Controls.Add(this.label1);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Name = "Star";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "EXPERIMENT";
			((System.ComponentModel.ISupportInitialize)(this.sbStatus)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		private void Star_Closing(object sender, CancelEventArgs e)
		{
			if(timer!=null)
				timer.Stop();
			timer2.Stop();
			timer3.Stop();
			if(ITimerOn != null) ITimerOn.Stop();
			if(ITimerSpace != null)ITimerSpace.Stop();

			if(Summary==false)
				this.WriteSummary();
			if(iwriter!=null)
			{
				try
				{
					iwriter.Flush();
					iwriter.Close();
				}
				catch(Exception){}
			}
			try
			{
				player.Stop();
				player.Close();
				Primary = null;
				Secondary = null;
				game.Close();
				game = null;
			}
			catch(Exception ex)
			{
			}
			finally 
			{
				mainmenu.Show();
			}
			mainmenu.Show();
		}
		

		public void Init()
		{
			this.sbStatus.Text = "Status: Ready";
			iwriter = new StreamWriter(outfile.FullName+".dat",false);
			iwriter.WriteLine("HAL trial by trial");
			iwriter.WriteLine(string.Empty);
			iwriter.WriteLine("SUBJECT DATA");
			iwriter.WriteLine(mainmenu.txtName.Text);
			iwriter.WriteLine(mainmenu.txtBirth.Text);
			iwriter.WriteLine(mainmenu.cmbGender.Text);
			iwriter.WriteLine(mainmenu.txtGroup.Text);
			iwriter.WriteLine(mainmenu.txtId.Text);
			iwriter.WriteLine(mainmenu.def.strInitFile);
			iwriter.WriteLine(DateTime.Now.ToShortDateString());
			iwriter.WriteLine(DateTime.Now.ToShortTimeString());
			iwriter.WriteLine(string.Empty);
			iwriter.WriteLine("Actual,Desired,Correct");

			lblCal.Text = mainmenu.GetCal();
			player.Init();
			game = new StarGame.GameForm(mainmenu.def.bSingleScreen,mainmenu.def.FeedbackLoc,mainmenu.def.FeedbackSize);
			game.ShowPoints = false;
			game.Show();
			game.ButtonEvt+=new StarGame.GameForm.ButtonEventHandler(game_ButtonEvt);
			game.KeyEvt += new StarGame.GameForm.KeyEventHandler(game_KeyEvt);
			game.SetupGame(mainmenu.def.strFeedbackDir,(string) mainmenu.def.Feedback[Primary.nCurrentGame]);
			game.DrawButtons(mainmenu.def.Buttons);
			foreach (Button b in mainmenu.def.Buttons)
			{
				if(b.Text.Length == 1) iNumButton ++; //count buttons that are A, B, C etc but not 'Repeat', 'No difference' etc
			}  

			nDelay = mainmenu.def.nGameDelay;

			this.nAdaptType = mainmenu.def.nAdaptType;
			if(nAdaptType>0)
			{
				this.btnSkip.Enabled = false;
				this.btnReset.Enabled = false;
			}
			//we are, at this time, limited to level, so I'm going to set that here, manually  3/2/06
            //Primary.AdaptType = mainmenu.def.PrimaryAdapt;
			Primary.AdaptType = AdaptiveTypes.Level;
			Primary.nStepType = 1;
			Primary.nStepSize = mainmenu.def.nPrimaryStep;
			bBandwidth = mainmenu.def.bBandwidth;
			PrimaryAR.nStepSize = mainmenu.def.nSecondaryStep;
			PrimaryAR.StdErrVal = mainmenu.def.dwStdErrVal;
			PrimaryAR.PrimaryReversals = mainmenu.def.nChangeReversals;
			PrimaryAR.Mode = mainmenu.def.nStopMode;
			PrimaryAR.NumOfReversals = mainmenu.def.nStopReversals;
			if(PrimaryAR.Mode==1)//stopping on number of reversals
				label9.Text = "Num of Reversals:";

			if(mainmenu.def.bFrequencyShaping==true)
			{
				FileInfo f = new FileInfo(mainmenu.txtFreqShape.Text); 
				txtMFile.Text = f.Name;
			}
			
			if(InitStims()==false)
			{
				this.Close();
				game.Close();
				mainmenu.Show();
				return;
			}
			this.Show();
			if(Secondary.nTotalStims>0)
				bSecondary = true;

			timer = new Timer();
			timer.Interval = mainmenu.def.nTimer;
			timer.Tick += new EventHandler(timer_Tick);
			
			timer2 = new Timer();
			timer2.Interval = mainmenu.def.nDelay;
			timer2.Tick += new EventHandler(timer2_Tick);
			timerCatch = new Timer();
			timerCatch.Interval = mainmenu.def.nCatchLength;
			timerCatch.Tick += new EventHandler(timerCatch_Tick);
			timer3 = new Timer();
			timer3.Interval = 300;
			timer3.Tick += new EventHandler(timer3_Tick);

			if(mainmenu.def.bInterval==true)
				InitInterval();
			InitCompleted();
			InitRight();
			InitWrong();
			InitList();
			WriteStart();

			lblKey.Text = "Keys:\r\n"+
				"P - Pause\r\n"+
				"C - Continue\r\n"+
				"R - Reset\r\n"+
				"S - Skip";

			DialogResult r;
			if(mainmenu.def.bWaitForNextButton==true)
			{
				//if we are using a next button, wait for the user to click 'next' before presenting
				r = MessageBox.Show(this.game,"Click 'OK' when you are ready to begin, or 'Cancel' to abort!","Ready?",MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
			}
			else
					r = MessageBox.Show(this,"Click 'OK' when you are ready to begin, or 'Cancel' to abort!","Ready?",MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
			if(r == DialogResult.OK)
				StartStar();
			else
				this.Close();
		}

		private bool InitStims()
		{
			try
			{
				Progress progress = new Progress();
				progress.Init("Initializing Simuli",mainmenu.def.PrimaryStims.Count+mainmenu.def.SecondaryStims.Count,0,0);
				progress.Update();
				progress.Show();
				Application.DoEvents();
				Stim s;
				#region Masker
				if(mainmenu.def.Masker!=null)
				{
					s = (Stim) mainmenu.def.Masker;
					if(s.nFreq>0)//if there is a frequency value
						s.buffer.Tone(mainmenu.MaxAmplitude,s.nFreq,s.nPhase,s.nLength,s.nRise,s.nFreq,s.strEar,s.bLoop);
					else
					{
						FileInfo f = new FileInfo(s.strStimDirectory+"\\"+s.strFile);//new FileInfo(mainmenu.def.strStimDirectory+"\\"+s.strFile);
						s.buffer.WaveFile(f,mainmenu.MaxAmplitude,s.strEar,s.bLoop,s.AmpType);
					}
					s.buffer.ToBePlayed = false;
					double d = mainmenu.CalDb;
					double fLevel = s.fThreshold - d;
					double V2 = mainmenu.MaxAmplitude*(Math.Pow(10,fLevel/20));
					if(V2>mainmenu.MaxAmplitude)
						V2 = mainmenu.MaxAmplitude;
					s.buffer.SetLevel((int)V2);
					s.buffer.Play();
					Masker = s;
					player.Signals[2] = Masker.buffer;
				
				}
				#endregion

				#region PrimaryStims
				if(mainmenu.def.PrimaryStims.Count>0)
				{
					for(int i=0;i<mainmenu.def.PrimaryStims.Count;i++)
					{
						progress.Increment();
						s = (Stim) mainmenu.def.PrimaryStims[i];
						if(s.strType=="PAUSE")
						{
							int x=0;
							x++;
							//just need it added to the set
						}
						else if(s is ComplexStim)
						{
							ComplexStim cs = (ComplexStim) s;
							for(int j=0;j<cs.nNumberOfStims;j++)
							{
								Stim sub = (Stim) cs.listStims[j];
								mainmenu.CreateStim(ref sub);
								int nLevel = mainmenu.GetV2(sub.nOrigin,sub.nFreq,sub.strEar);
								sub.buffer.SetLevel(nLevel);
							}
						}
						else if(s.nFreq>0)//if there is a frequency value
						{
							Stim a = (Stim) mainmenu.def.PrimaryStims[i];
							s = new Stim();
							s = a.Clone();
							s.strEar = a.strEar;
							//s.nMethod = meth;
							s.nFreq = a.nFreq;
							s.buffer = new WaveBuffer();
							mainmenu.CreateStim(ref s);
						}
						else
						{
							/*
							if(s.strEar=="left")
							{
								FileInfo f = new FileInfo(mainmenu.def.strStimDirectory+s.strFile);
								if(mainmenu.def.bFrequencyShaping==false)
									s.buffer.WaveFile(f,mainmenu.MaxAmplitude,s.strEar,false,s.AmpType);
								else
								{
									progress.SetLabel("Frequency Shaping...");
									progress.Increment();
									progress.Update();
									Application.DoEvents();
									//altered 2/14/07 to max scale the waveform, if not set to none
									int V2 = mainmenu.GetV2((int)mainmenu.CalDb,1000,"both");
									WaveBuffer bt;
									if(s.AmpType!=AmplificationTypes.None)
										bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,V2);
									else
										bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,0);
									s.buffer.SetMS(bt.ms, s.strEar);
									if(s.buffer==null)
									{
										MessageBox.Show("Error FreqShaping stim: " + s.strFile);
										return false;
									}
								}
							}
							else */
							{ 
								FileInfo f =new FileInfo(s.strStimDirectory+"\\"+s.strFile);// new FileInfo(mainmenu.def.strStimDirectory+s.strFile);
								if(mainmenu.def.bFrequencyShaping==false)
									s.buffer.WaveFile(f,mainmenu.MaxAmplitude,s.strEar,false,s.AmpType);
								else
								{
									progress.SetLabel("Frequency Shaping...");
									progress.Increment();
									progress.Update();
									Application.DoEvents();
									int V2 = mainmenu.GetV2((int) mainmenu.CalDb,1000,"both");
									WaveBuffer bt;
									if(s.AmpType!=AmplificationTypes.None)
										bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,V2);
									else
										bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,0);
									s.buffer.SetMS(bt.ms, s.strEar);
									if(s.buffer==null)
									{
										MessageBox.Show("Error FreqShaping stim: " + s.strFile);
										return false;
									}
								}

							}
						}
						s.buffer.AmplificationType = s.AmpType;
						s.buffer.ToBePlayed = false;
						if(mainmenu.def.nAdaptType>0)
						{
							s.nMethod = (int) mainmenu.def.Methods[0];
							Primary.Stims.Add(s);
							/*foreach(int n in mainmenu.def.Methods)
							{
								Stim ss = s.Clone();
								ss.nMethod = n;
								Primary.Stims.Add(ss);
							}*/
						}
						else if(mainmenu.def.nStepSize!=0)//if I'm supposed to vary them
						{
							for(int ii=0;ii<=mainmenu.def.nRange/mainmenu.def.nStepSize;ii++)
							{
								Stim ss = s.Clone();
								ss.nOrigin = s.nOrigin-ii*mainmenu.def.nStepSize;
								for(int xx=0;xx<mainmenu.def.nReps;xx++)
									Primary.Stims.Add(ss);
							}
						}
						else
						{
							for(int xx=0;xx<mainmenu.def.nReps;xx++)
								Primary.Stims.Add(s);
						}
					}
				}
				#endregion

				#region SecondaryStims
				if(mainmenu.def.SecondaryStims.Count>0)
				{
					progress.SetLabel("Loading Secondaries...");
					progress.Increment();
					progress.Update();
					Application.DoEvents();
					for(int kk=0;kk<mainmenu.def.SecondaryStims.Count;kk++)
					{
						s = (Stim) mainmenu.def.SecondaryStims[kk];
						progress.Increment();
						if(s is ComplexStim)
						{
							ComplexStim cs = (ComplexStim) s;
							for(int j=0;j<cs.nNumberOfStims;j++)
							{
								Stim sub = (Stim) cs.listStims[j];
								mainmenu.CreateStim(ref sub);
								int nLevel = mainmenu.GetV2(sub.nOrigin,sub.nFreq,sub.strEar);
								sub.buffer.SetLevel(nLevel);
							}
						}
						else if(s.nFreq>0)//if there is a frequency value
						{
							Stim a = (Stim) mainmenu.def.SecondaryStims[kk];
							s = new Stim();
							s = a.Clone();
							//s.strEar = a.strEar;//shouldn't be needed, included with clone
							//s.nFreq = a.nFreq;
							s.buffer = new WaveBuffer();
							mainmenu.CreateStim(ref s);
						}
						else
						{
							FileInfo f =new FileInfo(s.strStimDirectory+"\\"+s.strFile);// new FileInfo(mainmenu.def.strStimDirectory+s.strFile);
							if(mainmenu.def.bFrequencyShaping==false||mainmenu.def.nFreqShapeSecondary==2)
								s.buffer.WaveFile(f,mainmenu.MaxAmplitude,s.strEar,s.bLoop,s.AmpType);
							else
							{
								progress.SetLabel("Frequency Shaping...");
								progress.Increment();
								progress.Update();
								Application.DoEvents();
								int V2 = mainmenu.GetV2((int)mainmenu.CalDb,1000,"both");
								WaveBuffer bt;
								if(s.AmpType!=AmplificationTypes.None)
									bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,V2);
								else
									bt = SigPro.FreqShape(f,mainmenu.def.LAtten,mainmenu.def.LFreqs,mainmenu.def.RAtten,mainmenu.def.RFreqs,0);
								s.buffer.SetMS(bt.ms, s.strEar);
								if(s.buffer==null)
								{
									MessageBox.Show("Error FreqShaping stim: " + s.strFile);
									return false;
								}
								
							}
							
						}
						s.buffer.ToBePlayed = false;
						s.buffer.AmplificationType = s.AmpType;
						if(mainmenu.def.bSecondaryContinuous==true)
							s.bLoop=true;
						Secondary.Stims.Add(s);
					}
				}
				#endregion
				Primary.nTotalStims = Primary.Stims.Count;
				Secondary.nTotalStims = Secondary.Stims.Count;

				progress.SetLabel("Generating Play List...");
			//	progress.Increment();
				progress.Update();
				Application.DoEvents();
				//Randomize
				//randomizes order of primary and secondary
				//but plays all primary for one secondary, then moves to next secondary.
				Randomize();
				/*
				 * Move this code into Randomize, so that the decision making is done there
				if(mainmenu.def.bRandom==true&&mainmenu.def.strSecondaryOrder!="block"||
					mainmenu.def.bRandom&&mainmenu.def.SecondaryStims.Count==0)
				{
					Randomize();
				}
				else if(mainmenu.def.SecondaryStims.Count>0&&mainmenu.def.strSecondaryOrder!="block")
					RandomizeSecondary();
				else if(mainmenu.def.bRandom==true)
					RandomizePrimary();
				//For two way random
				//For a random list where both the primary and secondary are in random order.
				if(mainmenu.def.strSecondaryOrder=="random")
				{
					TwoWayRandom = new ArrayList();
					this.bTwoWay = true;
					InitTwoWayRandom();
				}
				*/

				progress.Close();
				ShowTotal(Primary.Stims.Count);
			}
			catch(Exception exc /*err*/)
			{
				MessageBox.Show("Error in Stimulus Initialization.  Please check your .def file and .wav files" + exc.Message,"Parse Error",
					MessageBoxButtons.OK,MessageBoxIcon.Stop);
				return false;
			}
			return true;
		}
		private void Randomize()
		{
			if(mainmenu.def.bRandom==true&&mainmenu.def.strSecondaryOrder!="block"||
				mainmenu.def.bRandom&&mainmenu.def.SecondaryStims.Count==0)
			{
				#region SimpleRandom
				Primary.RandomOrder = new ArrayList();
				Random r = new Random(System.DateTime.Now.Millisecond);
				while(Primary.RandomOrder.Count < Primary.Stims.Count)
				{
					int n = r.Next(Primary.Stims.Count);
					if(Primary.RandomOrder.IndexOf(n)<0)
					{
						Primary.RandomOrder.Add(n);
					
					}
				}
				Secondary.RandomOrder = new ArrayList();
				r = new Random(System.DateTime.Now.Millisecond);
				while(Secondary.RandomOrder.Count < Secondary.Stims.Count)
				{
					int n = r.Next(Secondary.Stims.Count);
					if(Secondary.RandomOrder.IndexOf(n)<Secondary.Stims.Count)
					{
						if(Secondary.RandomOrder.IndexOf(n)<0)
						{
							Secondary.RandomOrder.Add(n);
						
						}
					}
				}
				#endregion
			}
			else if(mainmenu.def.SecondaryStims.Count>0&&mainmenu.def.strSecondaryOrder!="block")
				RandomizeSecondary();
			else if(mainmenu.def.bRandom==true)
				RandomizePrimary();
			//For two way random
			//For a random list where both the primary and secondary are in random order.
			if(mainmenu.def.strSecondaryOrder=="random")
			{
				TwoWayRandom = new ArrayList();
				this.bTwoWay = true;
				InitTwoWayRandom();
			}
		}
		private void RandomizePrimary()
		{
			Primary.RandomOrder = new ArrayList();
			Random r = new Random(System.DateTime.Now.Millisecond);
			while(Primary.RandomOrder.Count < Primary.Stims.Count)
			{
				int n = r.Next(Primary.Stims.Count);
				if(Primary.RandomOrder.IndexOf(n)<0)
				{
					Primary.RandomOrder.Add(n);
					
				}
			}
		}
		
		private void RandomizeSecondary()
		{
			if(Secondary.RandomOrder!=null)
				Secondary.RandomOrder.Clear();	
			else
				Secondary.RandomOrder = new ArrayList();
			Random r = new Random(System.DateTime.Now.Millisecond);
			while(Secondary.RandomOrder.Count < Secondary.Stims.Count)
			{
				int n = r.Next(Secondary.Stims.Count);
				if(Secondary.RandomOrder.IndexOf(n)<Secondary.Stims.Count)
				{
					if(Secondary.RandomOrder.IndexOf(n)<0)
					{
						Secondary.RandomOrder.Add(n);
					}
				}
			}
			Secondary.nCurrentStim = -1;
		}
		
		private void InitTwoWayRandom()
		{
			if(mainmenu.def.bRandom==true&&mainmenu.def.strSecondaryOrder=="random"&&mainmenu.def.nAdaptType==0)
			{
				LeiboldRandom();
				return;
			}
			int P = mainmenu.def.PrimaryStims.Count*mainmenu.def.nReps;
			int S = mainmenu.def.SecondaryStims.Count;
			Random r = new Random(DateTime.Now.Millisecond);
			ArrayList list = new ArrayList();
			int x=0;
			int[] y;
			//init a list with all combinations
			for(int i=0;i<P;i++)
			{
				for(int j=0;j<S;j++)
				{
					y = new int[2];
					y[0] = i;
					y[1] = j;
					x++;
					list.Add(y);
				}
			}
			//add them to the master list in random order
			while(list.Count>0)
			{
				x = r.Next(list.Count);
				y = (int[]) list[x];
				TwoWayRandom.Add(y);
				list.Remove(y);
			}
		}
		private void LeiboldRandom()
		{
			//play each primary with a secondary
			Random rand = new Random(DateTime.Now.Millisecond);
			int[] y;
			int P = Primary.Stims.Count;
			int S = Secondary.Stims.Count;
			ArrayList list = new ArrayList();
			ArrayList listS = new ArrayList();
			for(int i=0;i<S;i++)
			{
				listS.Add(i);
			}
			for(int i=0;i<P;i++)
			{
				y = new int[2];
				y[0] = i;
				int n = rand.Next(listS.Count);
				y[1] = (int) listS[n];
				listS.RemoveAt(n);
				if(listS.Count==0)
				{
					for(int k=0;k<S;k++)
					{
						listS.Add(k);
					}
				}
				list.Add(y);
			}
			int x;
			while(list.Count>0)
			{
				x = rand.Next(list.Count);
				y = (int[]) list[x];
				TwoWayRandom.Add(y);
				list.Remove(y);
			}
		}
		private void InitList()
		{
			try
			{
				ColumnHeader c  = new ColumnHeader();
				c.Text = "Primary Stim";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "PresLevel";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "SecStim";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "SecPresLevel";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				/*if(mainmenu.def.bPrimaryAdaptive==true)
					c.Text = "CornerFreq";
				else*/
					c.Text = "AltCat";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Stim Cat";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Response";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Correct";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Action";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Method";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Ear";
				c.Width = -2;
				listView1.Columns.Add(c);
				listView1.Update();

				foreach(ColumnHeader ch in listView1.Columns)
					ch.Width=-2;

				string strTemp=string.Empty;
				foreach(string str in mainmenu.def.listRes)
				{
					if(str=="perf"||str=="freq")
						strTemp = GetColumn(str);
					else
					{
						c = new ColumnHeader();
						c.Text = GetColumn(str);
						listView2.Columns.Add(c);
					}
				}
				if(mainmenu.def.nAdaptType>0)//if any adaptive
				{
					c = new ColumnHeader();
					c.Text = this.Primary.AdaptType.ToString();
					mainmenu.def.listRes.Add(c.Text);
					listView2.Columns.Add(c);
				}
				else
				{
					//non adaptive
					c = new ColumnHeader();
					c.Text = GetColumn(strTemp);
					listView2.Columns.Add(c);
					InitStat();
				}
			
				foreach(ColumnHeader ch in listView2.Columns)
					ch.Width=-2;
			}
			catch(Exception err)
			{
				MessageBox.Show("Error configuring result data structures: " + err.Message);
			}
		}
		private void InitStat()
		{
			ArrayList lists = new ArrayList();
			ArrayList listCols = new ArrayList();
			foreach(string str in mainmenu.def.listRes)
			{
				if(str=="perf"||str=="freq")
					continue;
				listCols.Add(str);
				ArrayList listTemp = new ArrayList();
				if(str=="response")
				{
					foreach(Button b in mainmenu.def.Buttons)
					{
						ButtonTag bt = (ButtonTag) b.Tag;
						listTemp.Add((string)bt.strCat);
					}
				}
				else if(str!="secondarystim")
				{
					foreach(Stim s in Primary.Stims)
					{
						string Value = GetField(s,str);
						if(listTemp.Contains(Value)==false)
							listTemp.Add(Value);
					}
				}
				else
				{
					foreach(Stim s in Secondary.Stims)
					{
						if(s.nFreq>0)
							listTemp.Add(s.nFreq.ToString());
						else
							listTemp.Add(s.strFile);
					}

				}
				lists.Add(listTemp);
			}
			int x = 1;
			foreach(ArrayList l in lists)
			{
				x*=l.Count;
			}
			listStats = new ArrayList();
			int y=0;
			//if(mainmenu.def.nAdaptType>0)
				y++;
			MakeStat(y,(string)mainmenu.def.listRes[y-1],lists);	
		}
		private void InitInterval()
		{
			bInterval = true;
			ITimerOn = new Timer();
			ITimerOn.Interval = mainmenu.def.nIntervalLen;
			ITimerOn.Tick += new EventHandler(ITimerOn_Tick);
			ITimerSpace = new Timer();
			ITimerSpace.Interval = mainmenu.def.nIntervalSpace;
            ITimerSpace.Tick += new EventHandler(ITimerSpace_Tick);
			int zz = 1;
			if(mainmenu.def.bWaitForNextButton==true)
				zz++;
			//	iNumButton++;
			int nB =mainmenu.def.Buttons.Count-zz;// mainmenu.def.Buttons.Count - iNumButton; // 
			IntervalList = new ArrayList();
			int nX = 0;
			for(int i=0;i<100;i++)
			{
				IntervalList.Add(nX++);
				if(nX==nB)
					nX = 0;
			}
			int nLen = mainmenu.def.nIntervalLen;
			foreach(Stim s in this.Primary.Stims)
			{
				if(s is ComplexStim)
				{
				}
				else
					s.buffer.SetLength(nLen);
			}
			foreach(Stim s in this.Secondary.Stims)
			{
				if(s is ComplexStim)
				{
				}
				else
					s.buffer.SetLength(nLen);
			}
		}
		
		private void MakeStat(int nCol,string strCol,ArrayList lists)
		{
			//calls itself recursively.
			//it's a mess!  
			//Thank Andrea.  It's her fault.

			ArrayList l = (ArrayList) lists[nCol-1];
			//lists.RemoveAt(0);
			
			foreach(string str in l)
			{
				bool b = false;
				if(nCol<lists.Count)
				{
					MakeStat(nCol+1,(string)mainmenu.def.listRes[nCol+1],lists);
					foreach(Stat s in this.listStats)
					{
						switch (strCol)
						{
							case "primarystim":
								if(s.strPrimary.Length==0)
								{
									s.strPrimary = str;
									b = true;
								}
								break;
							case "ear":
								if(s.strEar.Length==0)
								{
									s.strEar = str;
									b = true;
								}
								break;
							case "stimcat":
								if(s.strStimCat.Length==0)
								{
									s.strStimCat = str;
									b = true;
								}
								break;
							case "altcat":
								if(s.strAltCat.Length==0)
								{
									s.strAltCat = str;
									b = true;
								}
								break;
							case "secondarystim":
								if(s.strSecondary.Length==0)
								{
									s.strSecondary = str;
									b = true;
								}
								break;
							case "response":
								if(s.strResponse.Length==0)
								{
									s.strResponse = str;
									b = true;
								}
								break;
						}//switch str
					}//foreach stat
				}
				else
				{
					Stat s = new Stat();
					switch (strCol)
					{
						case "primarystim":
							s.strPrimary = str;
							break;
						case "ear":
							s.strEar = str;
							break;
						case "stimcat":
							s.strStimCat = str;
							break;
						case "altcat":
							s.strAltCat = str;
							break;
						case "secondarystim":
							s.strSecondary = str;
							break;
						case "response":
								s.strResponse = str;
							break;
					}
					listStats.Add(s);
				}
				
			}
		}
			
		
		private string GetColumn(string str)
		{
			switch (str)
			{
				case "primarystim":
					return "Primary Stim";
				case "perf":
					return "Perf";
				case "freq":
					return "Freq";
				case "ear":
					return "Ear";
				case "stimcat":
					return "StimCat";
				case "altcat":
					return "AltCat";
				case "method":
					return "Method";
				case "secondarystim":
					return "Secondary Stim";
				case "response":
					return "Response";
				default:
					return str.ToUpper();
			}
		}

		private string GetField(string str)
		{
			switch (str)
			{
				case "primarystim":
					if(mainmenu.def.nAdaptType<=1)
					{
						if(Primary.CurrentStim.nFreq>0)
							return Primary.CurrentStim.strType + " " +Primary.CurrentStim.nFreq.ToString();
						else
							return Primary.CurrentStim.strFile;
					}
					else
					{
						if(Secondary.CurrentStim.nFreq>0)
							return Secondary.CurrentStim.strType + " " +Secondary.CurrentStim.nFreq.ToString();
						else
							return Secondary.CurrentStim.strFile;
					}
				case "perf":
					return "Perf";
				case "freq":
					return "Freq";
				case "response":
					return Primary.CurrentResponse;
				case "ear":
					return Primary.CurrentStim.strEar;
				case "stimcat":
					return Primary.CurrentStim.strDesiredResponse;
				case "altcat":
					return Primary.CurrentStim.strInfo;
				case "method":
					return Primary.CurrentStim.nMethod.ToString();
				case "secondarystim":
					if(Secondary.CurrentStim.nFreq>0)
						return Secondary.CurrentStim.nFreq.ToString();
					else
						return Secondary.CurrentStim.strFile;
				case "Level":
					if(mainmenu.def.nAdaptType==2)
					{
						string strTemp;
						if(Secondary.CurrentStim is ComplexStim)
						{
							strTemp = string.Empty;
							ComplexStim cs = (ComplexStim) Secondary.CurrentStim;
							foreach(Stim sub in cs.listStims)
							{
								if(sub.bAdapt==true)
								{
									strTemp += string.Format("Stim:{0} {1} Thresh: {2}  ",
										sub.strType,sub.nFreq,sub.nOrigin+Secondary.CurrentStim.fThreshold);
								}
							}
						}
						else
						{
							strTemp = string.Format("Threshold: {0}  SD: {1}",
								Secondary.CurrentStim.fThreshold.ToString("####.##"),PrimaryAR.standardError.ToString("####.##"));
						}
						return strTemp;
					}
					else
					{
						string strTemp;
						if(Primary.CurrentStim is ComplexStim)
						{
							strTemp = string.Empty;
							ComplexStim cs = (ComplexStim) Primary.CurrentStim;
							foreach(Stim sub in cs.listStims)
							{
								if(sub.bAdapt==true)
								{
									strTemp += string.Format("Stim:{0} {1} Thresh: {2}  ",
										sub.strType,sub.nFreq,sub.nOrigin+Primary.CurrentStim.fThreshold);
								}
							}
						}
						else
						{
							strTemp = string.Format("Threshold: {0}  SD: {1}",
								Primary.CurrentStim.fThreshold.ToString("####.##"),PrimaryAR.standardError.ToString("####.##"));
						}
						return strTemp;
					}
				case "LowPass":
				case "HiPass":
					return Primary.nCurrentCutoff.ToString();
				case "BandPass":
				case "BandStop":
					return Primary.nCurrentCutoff + " - " + Primary.F2;
				case "MFile":
					return string.Empty;
	
				default:
					return str.ToUpper();
			}

		}
		private string GetField(Stat s, string str)
		{
			switch (str)
			{
				case "primarystim":
					return s.strPrimary;
				case "ear":
					return s.strEar;
				case "stimcat":
					return s.strStimCat;
				case "altcat":
					return s.strAltCat;
				case "secondarystim":
					return s.strSecondary;
				case "response":
					return s.strResponse;
				default:
					return string.Empty;
			}

		}
		private string GetField(Stim s, string str)
		{
			switch (str)
			{
				case "primarystim":
					if(s.nFreq>0)
						return s.nFreq.ToString();
					else
						return s.strFile.Trim();
				case "ear":
					return s.strEar.Trim();
				case "stimcat":
					return s.strDesiredResponse;
				case "altcat":
					return s.strInfo.Trim();
				case "method":
					return s.nMethod.ToString().Trim();
				default:
					return str.ToUpper().Trim();
			}

		}
		private void StartStar()
		{
			Summary = false;
			System.Threading.Thread.Sleep(2000);
			this.Update();
			dtStarted = System.DateTime.Now;
			if(mainmenu.def.Masker!=null)
			{
				//player.Signals[2] = mainmenu.def.Masker.buffer;
				player.Signals[2].Play();
				player.Play();
			}
			try
			{
				if(bSecondary)
					GetSecondaryStim();
				/*if(mainmenu.def.strSecondaryOrder=="randomtrial"||mainmenu.def.strSecondaryOrder=="inorder")
					Secondary.nCurrentStim=-1;*/
				GetPrimaryStim();
				PresentPrimaryStim();
			}
			catch(Exception err)
			{
				MessageBox.Show("Error: " + err.Message);
				mainmenu.Show();
				this.Close();
			}

		}
		private bool GetPrimaryStim()
		{
			if(bFirst == false)
			{
				if(mainmenu.def.nAdaptType==1)//Primary Adapt
				{
					Primary.CurrentStim.Responses = PrimaryAR.Responses;
					Primary.CurrentStim.Levels = Primary.Levels;
					PrimaryAR.Clear();
					Primary.Levels.Clear();
					Primary.CalcLevels.Clear();
					Primary.nStepType = 1;
					Primary.nStepSize = mainmenu.def.nPrimaryStep;
					Primary.nCurrentLevel = (int) Primary.CurrentStim.nOrigin;
					Primary.nTrialCount = 0;
					Primary.bZeroed = false;
				}
				int n = Primary.Stims.IndexOf(Primary.CurrentStim);
				//Primary.Stims.RemoveAt(n);
				//Primary.Stims.Insert(n,Primary.CurrentStim);
				Primary.nCurrentStim++;
			}
			game.SetProgressBar(Primary.nCurrentStim);
			if(Primary.Stims.Count<=Primary.nCurrentStim)
				return false;
			if(mainmenu.def.bRandom==true&&bTwoWay==false)
			{
				int n = (int) Primary.RandomOrder[Primary.nCurrentStim];
				Primary.CurrentStim = (Stim) Primary.Stims[n];
			}
			else if(this.bTwoWay==true)
			{
				//Set primary and secondary stim
				if(TwoWayRandom.Count<=0)
					return false;
				int[] y = (int[]) TwoWayRandom[0];
				Primary.CurrentStim = (Stim) Primary.Stims[y[0]];
				Secondary.CurrentStim = (Stim) Secondary.Stims[y[1]];
				player.Signals[1] = Secondary.CurrentStim.buffer;
				Secondary.nCurrentLevel = Secondary.CurrentStim.nOrigin;
				this.ShowSecondaryStim(Secondary.CurrentStim);
				this.PresentSecondaryStim();
				TwoWayRandom.RemoveAt(0);
			}
			else
			{
				Primary.CurrentStim = (Stim) Primary.Stims[Primary.nCurrentStim];
			}
			if(Primary.CurrentStim.strType=="PAUSE")
			{
				btnPause_Click(null,null);
				return true;
			}
			Primary.nCurrentLevel = (int) Primary.CurrentStim.nOrigin;
			Primary.CatchTrial = false;
			PrimaryAR.SetMethod(Primary.CurrentStim.nMethod);
			nReversals = 0;
			this.ShowPrimaryStim(Primary.CurrentStim);
			if(Primary.CurrentStim is ComplexStim)
			{
				ComplexStim cs = (ComplexStim) Primary.CurrentStim;
				cs.Mix();
			}
			player.Signals[0] = Primary.CurrentStim.buffer;
			bFirst = false;
			if(Primary.AdaptType==AdaptiveTypes.LowPass||Primary.AdaptType==AdaptiveTypes.HiPass)
			{
				Primary.nCurrentLevel = (int) Primary.CurrentStim.fThreshold;
				InitFilter();
				ProcessPrimaryStim();
			}
			return true;
				
		}
		private void InitFilter()
		{
			if(Primary.AdaptType==AdaptiveTypes.LowPass||Primary.AdaptType==AdaptiveTypes.HiPass)
			{
				Primary.nCurrentCutoff = int.Parse(Primary.CurrentStim.strInfo);
			}
			else if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
			{
				int Fc = int.Parse(Primary.CurrentStim.strInfo);
				double exp = 1.0/Primary.nStepSize;
				double dd = Math.Pow(2.0,exp);
				double d = ((double)Primary.nCurrentCutoff)/dd;
				Primary.nCurrentCutoff = (int) d;
				d = ((double)Primary.nCurrentCutoff)*dd;
				Primary.F2 = (int) d;
			}
			ProcessPrimaryStim();
		}
		private bool GetSecondaryStim()
		{
			if(bSecondary==false)
				return true;
			if(this.bNewSecondary==true)
				return true;
			if(player.Signals[1] != null)
				player.Signals[1].Stop();
			if(bFirst == false)
			{
				if(mainmenu.def.nAdaptType==2)//Secondary Adapt
				{
					Secondary.CurrentStim.Responses = PrimaryAR.Responses;
					Secondary.CurrentStim.Levels = Secondary.Levels;
					//average last three levels
					float f=0.0f;
					foreach(int k in Secondary.CalcLevels)
					{
						f+=k;
					}
					Secondary.CurrentStim.fThreshold = f/(float)Secondary.CalcLevels.Count;
					PrimaryAR.Clear();
					PrimaryAR.SetMethod(Primary.CurrentStim.nMethod);
					Secondary.Levels.Clear();
					Secondary.CalcLevels.Clear();
					Primary.nStepType = 1;
					Primary.nStepSize = mainmenu.def.nPrimaryStep;
					Primary.nTrialCount = 0;
					Primary.bZeroed = false;
				}
				int n = Secondary.Stims.IndexOf(Secondary.CurrentStim);
				Secondary.Stims.RemoveAt(n);
				Secondary.Stims.Insert(n,Secondary.CurrentStim);
				Secondary.nCurrentStim++;
			}
			if(Secondary.Stims.Count<=Secondary.nCurrentStim)
				return false;
			int zz = Secondary.nCurrentStim;
			if(zz<0)
				zz=0;
			if(mainmenu.def.strSecondaryOrder!="block"&&mainmenu.def.strSecondaryOrder!="inorder")
			{
				int n = (int) Secondary.RandomOrder[zz];
				Secondary.CurrentStim = (Stim) Secondary.Stims[n];
			}
			else
			{
				Secondary.CurrentStim = (Stim) Secondary.Stims[zz];
			}
			Secondary.nCurrentLevel = (int) Secondary.CurrentStim.nOrigin;
			if(Secondary.CurrentStim is ComplexStim)
			{
				ComplexStim cs = (ComplexStim) Secondary.CurrentStim;
				cs.Mix();
			}
			player.Signals[1] = Secondary.CurrentStim.buffer;
			player.Signals[1].bLooping = Secondary.CurrentStim.bLoop;
			this.ShowSecondaryStim(Secondary.CurrentStim);
			PresentSecondaryStim();
			bNewSecondary = true;
			return true;
		}
		

		private void PresentPrimaryStim()
		{
			Primary.V2 = GetPrimaryLevel();
			
			//may need to play the primary stim as a cue
			if(mainmenu.def.bCue==true)
				PlayCue();

			ShowPrimaryLevel(Primary.nCurrentLevel);
			ShowStandardError();
			//track what we are doing
			if(mainmenu.def.nAdaptType==1||mainmenu.def.nAdaptType==3)//adapting a primary
			{
				if(Primary.AdaptType==AdaptiveTypes.Level)
				{
					Primary.Levels.Add(Primary.nCurrentLevel);
					//add to calc levels if there has been a reversal
					if(Primary.nStepType==2&&nReversals<PrimaryAR.Reversals)
					{
						Primary.CalcLevels.Add(Primary.nCurrentLevel);
						nReversals++;
					}
				}
				else if(Primary.AdaptType==AdaptiveTypes.LowPass || Primary.AdaptType==AdaptiveTypes.HiPass)
				{
					Primary.Levels.Add(Primary.nCurrentCutoff);
					Primary.CalcLevels.Add(Primary.nCurrentCutoff);
				}
			}
			Primary.nTrialCount++;

			if(bInterval==false)
			{
				DoNonInterval();
			}
			else if(bInterval==true)
			{
				DoInterval();
			}

			if(mainmenu.def.nSpecialPatNextButton==1)
			{
				if(this.nCompleted%2==1)
					game.LightNextButton();
			}
		}
		private void DoNonInterval()
		{
			if(DoCatchTrial()==true)
				return;
			Primary.CatchTrial = false;
			if(bSecondary==true)
			{
				if(mainmenu.def.strSecondaryOrder=="randomtrial"||mainmenu.def.strSecondaryOrder=="inorder")
				{
					//try to get a secondary
					if(GetSecondaryStim()==false)
					{
						if(mainmenu.def.strSecondaryOrder=="block")
						{
							//if it doesn't work, re-initialize the random list
							RandomizeSecondary();
						}
						else//in order
						{
							Secondary.nCurrentStim = 0;
						}
						//Get the first of the new order
						Secondary.CurrentStim = (Stim) Secondary.Stims[Secondary.nCurrentStim];
						player.Signals[1] = Secondary.CurrentStim.buffer;
						this.ShowSecondaryStim(Secondary.CurrentStim);
						PresentSecondaryStim();
					}
				}
				if(player.Signals[1].bLooping==false)
				{
					//player.Signals[1].Play();
					PresentSecondaryStim();
				}
			}
			ShowPrimaryLevel(Primary.nCurrentLevel);
			bButtons = true;
			if(player.Signals[0]!=null)
			{ 
				player.Signals[0].Stop();
				if(Primary.CurrentStim is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) Primary.CurrentStim;
					cs.SetLevel(Primary.nCurrentLevel,this.mainmenu);
					cs.Mix();
				}
				else
				player.Signals[0].SetLevel((int) Primary.V2);
				player.Signals[0].Play();
				player.Play();
			}
			//when the user hits pause while the stim is playing,
			//it isn't working.  Putting this here in the hopes that it'll take
			//care of that
			if(Paused==false)
				timer.Start();
		}
		private void DoInterval()
		{
			//we are using intervals
			bButtons = false;
			Button but = (Button) mainmenu.def.Buttons[mainmenu.def.Buttons.Count-1];
			but.BackColor = this.BackColor;
				
			//decide which interval to use
			Random r = new Random(DateTime.Now.Millisecond);
			if(IntervalList.Count<=1)
			{
				int nB = mainmenu.def.Buttons.Count-1;
				int nX = 0;
				for(int i=0;i<100;i++)
				{
					IntervalList.Add(nX++);
					if(nX==nB)
						nX = 0;
				}
			}
			strSec = string.Empty;//clearing the variable that will hold the names of the secondary stims
			int x = r.Next(IntervalList.Count);
			Primary.nInterval = (int) IntervalList[x];
			Primary.nCurrentInterval = 0;
			IntervalList.RemoveAt(x);
			Primary.CurrentStim.strDesiredResponse = Primary.nInterval.ToString();
			if(mainmenu.def.strSecondaryOrder=="randomtrial"||mainmenu.def.strSecondaryOrder=="inorder")
			{
				//try to get a secondary
				if(GetSecondaryStim()==false)
				{
					if(mainmenu.def.strSecondaryOrder=="block")
					{
						//if it doesn't work, re-initialize the random list
						RandomizeSecondary();
					}
					else//in order
					{
						Secondary.nCurrentStim = 0;
					}
					//Get the first of the new order
					Secondary.CurrentStim = (Stim) Secondary.Stims[Secondary.nCurrentStim];
					player.Signals[1] = Secondary.CurrentStim.buffer;
					this.ShowSecondaryStim(Secondary.CurrentStim);
					PresentSecondaryStim();
				}
			}
			IntervalPlay();
		}
		private bool DoCatchTrial()
		{
			if(mainmenu.def.bCatchTrial==false)
				return false;//not doing catch trials
			if(bInterval==true)
				return false;//not currently doing catch trials on Intervals
			if(mainmenu.def.bBackToBackCatch==false&&Primary.CatchTrial==true)
				return false;//don't do two in a row
			if(Primary.nCurrentLevel<=-15 && Primary.CatchTrial==true)
			{
				/*if we are doing back to back catch trials,
				 * and we are at the bottom of the range
				 * we may have just forced a catch trial
				 * but we don't want to force another one
				 * we want it to go on an play the stim
				 * then come back later and possibly force another one
				 **/
				return false;
			}
			
			//do we want to do a catch trial (only on non-interval?
			Random r = new Random(DateTime.Now.Millisecond);
			int x = r.Next(100);
			if(x<mainmenu.def.nCatchFreq||(Primary.nCurrentLevel<=-15 && ((int)Primary.Levels[Primary.Levels.Count-1])==-15))
			{
				//either we randomly decided to do a catch
				//or our last two levels were <= -15
				//NO catch trial after 5 positives here, just in aud
				Primary.CatchTrial = true;
				timerCatch.Start();
				this.txtCurrent.Text = "Catch Trial";
				bButtons = true;
				return true;
			}
			return false;
		}
		private int GetPrimaryLevel()
		{
			//set level
			double d = mainmenu.CalDb;
			double fLevel = Primary.nCurrentLevel - d;
			int V2 = (int) (mainmenu.MaxAmplitude*(Math.Pow(10,fLevel/20)) );
			if(V2>mainmenu.MaxAmplitude)
				V2 = mainmenu.MaxAmplitude;

			//only if it is not a wave
			if(Primary.CurrentStim.strType!="wave")
			{
				V2 = mainmenu.GetV2(Primary.nCurrentLevel,Primary.CurrentStim.nFreq,Primary.CurrentStim.strEar);
			}
			return V2;
		}
		private void PresentSecondaryStim()
		{
			ShowSecondaryStim(Secondary.CurrentStim);
			if(mainmenu.def.nAdaptType==2)//adapting the secondary
			{
				//secondary only adapts level, currently
				Secondary.Levels.Add(Secondary.nCurrentLevel);
				//add to calc levels if there has been a reversal
				if(Primary.nStepType==2&&nReversals<PrimaryAR.Reversals)
				{
					Secondary.CalcLevels.Add(Secondary.nCurrentLevel);
					nReversals++;
				}
				
			}
			Secondary.nTrialCount++;
			Secondary.V2 = GetSecondaryLevel();

			if(player.Signals[1]!=null)
			{
				player.Signals[1].Stop();
				if(Secondary.CurrentStim is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) Secondary.CurrentStim;
					cs.SetLevel(Secondary.nCurrentLevel,this.mainmenu);
					cs.Mix();
				}
				else
					player.Signals[1].SetLevel((int) Secondary.V2);
				player.Signals[1].Play();
				if(Secondary.CurrentStim.bLoop==true)
				{
					System.Threading.ThreadStart ts = new System.Threading.ThreadStart(this.ContinuousSecondary);
					System.Threading.Thread t = new System.Threading.Thread(ts);
					t.Start();
					//player.Play();
				}
			}
		}
		private void ContinuousSecondary()
		{
			player.Signals[1].bLooping=true;
			player.Play();
		}
		private int GetSecondaryLevel()
		{
			double d = mainmenu.CalDb;
			double fLevel = Secondary.nCurrentLevel - d;
			int V2 = (int) (mainmenu.MaxAmplitude*(Math.Pow(10,fLevel/20)) );
			if(V2>mainmenu.MaxAmplitude)
				V2 = mainmenu.MaxAmplitude;
			//only if it is not a wave
			if(Secondary.CurrentStim.strType!="wave")
			{
				V2 = mainmenu.GetV2(Secondary.nCurrentLevel,Secondary.CurrentStim.nFreq,Secondary.CurrentStim.strEar);
			}
			return V2;
		}
	
		private void PlayCue()
		{
//			bool bStreaming = player.bStreaming;
//			player.bStreaming = false;
			//stop all signals
			player.Stop();
			//play Primary stim as single play
			if(Primary.CurrentStim is ComplexStim)
			{
				ComplexStim cs = (ComplexStim) Primary.CurrentStim;
				cs.SetLevel(Primary.nCurrentLevel,this.mainmenu);
				cs.Mix();
			}
			else
				player.Signals[0].SetLevel((int) Primary.V2);
			player.Signals[0].Play();
			player.Play();
			System.Threading.Thread.Sleep(ITimerSpace.Interval);
			//shouldn't return until it is done playing
//			player.bStreaming = bStreaming;
			
		}
		private void IntervalPlay()
		{  
			int zz = 1;//subtract 1 from the number of buttons for the respond button
			if(mainmenu.def.bWaitForNextButton==true)
				zz++;//if we are using wait for next button, we will subtract 2 from the number of buttons
			
			if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-zz)//if we still have buttons to do
			//if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-iNumButton)
			{
				//May need to pick a new secondary
				if(mainmenu.def.strSecondaryOrder=="randominterval")
				{
					//try to get a secondary
					if(GetSecondaryStim()==false)
					{
						//if it doesn't work, re-initialize the random list
						RandomizeSecondary();
						//Get the first of the new order
						if(Secondary.nCurrentStim<=0||Secondary.nCurrentStim>Secondary.Stims.Count-1)
							Secondary.nCurrentStim = 0;
						Secondary.CurrentStim = (Stim) Secondary.Stims[Secondary.nCurrentStim];
						player.Signals[1] = Secondary.CurrentStim.buffer;
						this.ShowSecondaryStim(Secondary.CurrentStim);
						if(strSec.Length>0)
							strSec+= ", ";
						strSec += Secondary.CurrentStim.strFile;
						PresentSecondaryStim();
					}
					//put file name in strSec to be written to file later.
					if(strSec.Length>0)
						strSec += " - "+Secondary.CurrentStim.strFile;
					else
						strSec = Secondary.CurrentStim.strFile;
				}
				//if we are using a secondary, get it ready
				if(this.bSecondary==true)
					this.PresentSecondaryStim();

				Button b = (Button) mainmenu.def.Buttons[Primary.nCurrentInterval];//turn the button white
				b.BackColor = Color.Blue;
				this.game.Update();
				//do next button
				
				if(Primary.nInterval==Primary.nCurrentInterval)//if we're going to play the tone with this button
				{
					//play tone
					if(player.Signals[0]!=null)
					{
						//play the tone
						if(Primary.CurrentStim is ComplexStim)
						{
							ComplexStim cs = (ComplexStim) Primary.CurrentStim;
							cs.SetLevel(Primary.nCurrentLevel,this.mainmenu);
							cs.Mix();
						}
						else
							player.Signals[0].SetLevel((int) Primary.V2);
						bool bPlayed = false;
						if(bSecondary==true)
						{
							if(mainmenu.def.bMixSecondary)
							{
								MemoryStream ms = Mix();
								bPlayed = player.PlayMemoryStream(ms);
							}
							else
								bPlayed = player.PlayMemoryStream(player.Signals[0].ms);
			///				MemoryStream ms = Mix();
			///				bPlayed = player.PlayMemoryStream(ms);
							//		player.Signals[0].WriteWave(new FileInfo(@"C:\test.wav"));
						}
						else
						{
							bPlayed = player.PlayMemoryStream(player.Signals[0].ms);
							//player.Signals[0].WriteWave(new FileInfo(@"C:\test.wav"));
						}
						if(bPlayed==false)
						{
							MessageBox.Show("Audio Error!");
							bButtons = true;
							return;
						}
					}
					b.BackColor = this.BackColor;
					this.game.Update();
					Primary.nCurrentInterval++;
					//this is here so that we don't do the interstim interval 
					//when the next button is the respond button
					if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-zz)
				//	if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-iNumButton)
						ITimerSpace.Start();
					else
						IntervalPlay();
				}
				else
				{
					//if we are not playing the stim in this interval
					if(this.bSecondary==true)
					{
						player.PlayMemoryStream(player.Signals[1].ms);
						foreach(Button bb in mainmenu.def.Buttons)
							bb.BackColor = this.BackColor;
						this.game.Update();
						Primary.nCurrentInterval++;
						//this is here so that we don't do the interstim interval 
						//when the next button is the respond button
						if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-zz)
						//if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-iNumButton)
							ITimerSpace.Start();
						else
							IntervalPlay();

					}
					else
					{
						ITimerOn.Start();//no stim to take up that space
					}
				}
			}
			else
			{
				//turn 'Respond' button white.
				bButtons = true;
				System.Threading.Thread.Sleep(300);
				Button but = (Button) mainmenu.def.Buttons[mainmenu.def.Buttons.Count-zz];//(Button) mainmenu.def.Buttons[mainmenu.def.Buttons.Count-iNumButton]; 
				but.BackColor = Color.Green;
			}
		}
		private MemoryStream Mix()
		{
			MemoryStream ms = new MemoryStream((int)player.Signals[0].ms.Length);
			player.Signals[0].ms.Seek(0,SeekOrigin.Begin);
			player.Signals[1].ms.Seek(0,SeekOrigin.Begin);
			BinaryReader s0 = new BinaryReader(player.Signals[0].ms);
			BinaryReader s1 = new BinaryReader(player.Signals[1].ms);
			BinaryWriter r0 = new BinaryWriter(ms);
			int z;
			long j1 = player.Signals[0].ms.Length;
			long j2 = player.Signals[1].ms.Length;
			long j = 0;
			if(j1>j2)
				j = j1;
			else
				j = j2;
			for(int x=0;x<j/4;x++)
			{
				if(player.Signals[0].ms.Length/4-4<x)
					z = 0;
				else
					z = s0.ReadInt32();
				if(player.Signals[1].ms.Length/4-4<x)
					z += 0;
				else
					z += s1.ReadInt32();
				r0.Write(z);
			}
			ms.Seek(0,SeekOrigin.Begin);
			return ms;
		}
		
		private void timer_Tick(object sender, EventArgs e)
		{
			timer.Stop();
			bButtons = false;
			strButton = "9";
			CheckButton();		
		}

		private void timer2_Tick(object sender, EventArgs e)
		{
			timer2.Stop();
			//if in Across Primary mode, 
			//Get the new primary here
			if(mainmenu.def.nAdaptType==3)
			{
				int nC = Primary.nCurrentLevel;
				if(this.GetPrimaryStim()==false)
				{
					if(mainmenu.def.bRandom==true)
					{
						RandomizePrimary();
					}
					Primary.nCurrentStim=-1;
					GetPrimaryStim();
				}
				Primary.nCurrentLevel = nC;
			}
			PresentPrimaryStim();	
		}

		private void timerCatch_Tick(object sender, EventArgs e)
		{
			bButtons = false;
			timerCatch.Stop();
			this.strButton = "abcdef";
			//game.strButtonClicked = "abcdef";
			CheckButton();
		}

		private void timer3_Tick(object sender, EventArgs e)
		{
			timer3.Stop();
			//if(player.ibolArscRunning==true)
			if(player.Signals[0].Status!=WaveBuffer.WaveStatus.Done)
				timer3.Start();//wait for stim to finish
			else
			{
				if(bInterval==false)
					CheckButton();//interstim
			}
		}
	
		private void ITimerOn_Tick(object sender, EventArgs e)
		{
			ITimerOn.Stop();
			System.Threading.Thread.Sleep(300);//to compensate for play time
			for(int i=0;i<mainmenu.def.Buttons.Count;i++)
			{
				((Button)mainmenu.def.Buttons[i]).BackColor = this.BackColor;
			}
			this.game.Update();
			Primary.nCurrentInterval++;
			int zz = 1;//subtract 1 from the number of buttons for the respond button
			if(mainmenu.def.bWaitForNextButton==true)
				zz++;//if we are using wait for next button, we will subtract 2 from the number of buttons
			if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-zz)
			//if(Primary.nCurrentInterval<mainmenu.def.Buttons.Count-iNumButton)
				ITimerSpace.Start();
			else
				IntervalPlay();
		}

		private void ITimerSpace_Tick(object sender, EventArgs e)
		{
			ITimerSpace.Stop();
			this.IntervalPlay();
		}
		

		private void game_ButtonEvt(object sender, EventArgs e)
		{
			// if sound is playing, dont do anything
			//if (player.ibolArscRunning == true) return;
			

			if(bButtons==false&&player.ibolArscRunning==false)
			{
				if(timer2.Enabled==true)
				{
					timer2.Stop();
					timer2.Start();
				}
				return;
			}
			timerCatch.Stop();
			timer.Stop();
			Button b = (Button) sender;
			strButton = game.strButtonClicked.ToLower();
		//05/27/10 : following if statement removed as per discussions with Donna and Kanae
			// Decided we dont need to decrease desired response value by 1
			/*
			if(strButton.Length==1)
			{
				if(Char.IsNumber(strButton[0]))
					strButton = (Convert.ToInt32(strButton) -1).ToString();
			}
			*/
			if(strButton.ToLower()=="respond")
				return;
			if(bButtons==true&&player.ibolArscRunning==true&&this.bInterval==false)
			{
				bButtons=false;
				timer3.Start();
				return;
			}
			bButtons=false;
				
			if(bWaiting==true&&strButton!="nextstim")
			{
				//in waiting mode, but user hits something besides 'next'
				bButtons=true;
				bWaiting=true;
				return;
			}
			else if(bWaiting==false&&strButton=="nextstim")
			{
				//have a next button, but not in waiting mode, and the user hits 'next'
				bButtons = true;
				return;
			}
			else if(bWaiting==true&&strButton=="nextstim")
			{
				if(player.Signals[0].Status!=WaveBuffer.WaveStatus.Done)
				{
					bButtons=false;
					timer3.Start();
					return;
				}
				//If we are requiring that the user hit a 'next' button, handle that here
				bWaiting = false;
				bButtons = false;
				PresentPrimaryStim();
				return;
			}
			if(bInterval==false)
			{
				if(player.Signals[0].Status!=WaveBuffer.WaveStatus.Done)
					timer3.Start();//wait for stim to finish
				else
					CheckButton();//inter stim delay
			}
			else
			{
				//strButton = mainmenu.def.Buttons.IndexOf(b).ToString();
				CheckIntervalButton(strButton);
			}
		}
		private void CheckButton()
		{
			//strResponse = strButton;
			//just to be sure.  Trying to prevent it from playing the secondary
			//stim when user responds early.  Glitch I can't find elsewhere.
			/*if(Secondary.CurrentStim.bLoop==false&&player.Signals[2]==null)
				player.Stop();*/
			Primary.CurrentResponse = strButton;
			if(strButton=="respond")
				return;
			if(strButton=="repeat")
			{
				bButtons=true;
				if(Secondary.CurrentStim.bLoop==true)
				{
					//if we are looping, we aren't doing random trial, and we have to do this
					PresentPrimaryStim();
				}
				else
				{
					//so that in a randomtrial it plays the same stims for both
					if(player.Signals[1]!=null)
						player.Signals[1].Play();
					if(player.Signals[0]!= null)
						player.Signals[0].Play();
					player.Play();
				}
				return;
			}
			if(mainmenu.def.nSpecialPatNextButton==1)
				game.DarkNextButton();
			IncrementCompleted();

			bNewSecondary = false;
			nCount++;
			if(Primary.CatchTrial==true)//if we did a catch trial
			{
				if(Primary.CurrentStim.strDesiredResponse!=strButton)//they didn't click the Yes button
				{
					Primary.nCatches++;
					nR = 1;
					WriteCatch(1);
				}
				else if(Primary.CurrentStim.strDesiredResponse==strButton)
				{
					Primary.nFalse++;
					nR = 0;
					WriteCatch(0);
				}
			}
			else if(mainmenu.def.nAdaptType==0)//non adaptive, no catch trial
			{
				if(Primary.CurrentStim.strDesiredResponse.ToLower()==strButton)
				{
					nR=1;
					nCorrect++;
					IncrementRight();
					PositiveReturn();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Correct");
				}
				else
				{
					nR=0;
					IncrementWrong();
					NegativeReturn();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Incorrect");
				}
			}
			else//adaptive, not a catch trial
			{
				Action a;
				Primary.CurrentResponse = strButton;
				if(Primary.CurrentStim.strDesiredResponse.ToLower()==strButton)
				{
					a = PrimaryAR.AddResponse(true,Primary.nCurrentLevel);
					nCorrect++;
					nR = 1;
					IncrementRight();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Correct");
				}
				else
				{
					a = PrimaryAR.AddResponse(false,Primary.nCurrentLevel);
					nR = 0;
					IncrementWrong();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Inorrect");
				}
				if(a==Action.Complete)
				{
					PrimaryComplete();
					return;
				}
				if(a==Action.NStepSizeChange||a==Action.PStepSizeChange)
				{
					//Go to next step size
					Primary.CalcLevels.Clear();
					Primary.nStepType++;
					Primary.nStepSize = mainmenu.def.nSecondaryStep;
					nReversals=0;
				}
				if(a==Action.PositiveReturn || a==Action.PStepSizeChange)
					PositiveReturn();
				else if(a==Action.NegativeReturn|| a==Action.NStepSizeChange)
					NegativeReturn();
				else if(a==Action.None)
				{
					Primary.strAction = "NONE";
					WriteResult();
				}
			}
			//update the game
			if(nCount>=nDelay)
			{
				if(mainmenu.def.nGameDelayType==0&&mainmenu.def.nGameDelay>=1)
				{
					for(int kk=0;kk<nCorrect;kk++)
					{
						StepGame();
						System.Threading.Thread.Sleep(500);
					}
				}
				else
					StepGame();
				nCount=0;
				nCorrect=0;
			}
			game.Update();
			//Do we stop here?
			if(mainmenu.def.nNumberOfTrials==this.nCompleted)
			{
				this.bButtons = false;
				this.game.Close();
				bGlobalDone = true;
				player.Stop();
				this.WriteSummary();
				game.Finish();
				MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
				return;
			}
			Next();
			
		}
		private void Next()
		{
			if(bGlobalDone == false)
			{
				if(Primary.CurrentStim.strType=="PAUSE")
					return;
				//if we are moving right on to the next stim
				if(mainmenu.def.bWaitForNextButton==false)
				{
					Random r = new Random(DateTime.Now.Millisecond);
					double d = r.NextDouble();
					timer2.Interval = (int) (mainmenu.def.nDelay + d*mainmenu.def.nJitter);
					timer2.Start();
				}
				else
				{
					//we are using a next button
					//if in Across Primary mode, 
					//Get the new primary here
					if(mainmenu.def.nAdaptType==3)
					{
						int nC = Primary.nCurrentLevel;
						if(this.GetPrimaryStim()==false)
						{
							if(mainmenu.def.bRandom==true)
							{
								RandomizePrimary();
							}
							Primary.nCurrentStim=-1;
							GetPrimaryStim();
						}
						Primary.nCurrentLevel = nC;
					}
					this.bButtons = true;
					bWaiting = true;
				}
			}
		}

		private void CheckIntervalButton(string strButton)
		{
			Primary.CurrentResponse = strButton;
			if(strButton.ToLower()=="respond")
				return;
			//if(strButton.ToLower()=="no different")
			//{
			//	bButtons=true;
			//	return;
			//}
			if(strButton=="repeat")
			{
				bButtons=true;
				PresentPrimaryStim();
				return;
			}
			nCount++;
			IncrementCompleted();
			if(mainmenu.def.nAdaptType==0)//non adaptive
			{
				if(Primary.CurrentStim.strDesiredResponse.ToLower()==strButton)
				{
					nR=1;
					nCorrect++;
					IncrementRight();
					PositiveReturn();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Correct");
				}
				else
				{
					nR=0;
					IncrementWrong();
					NegativeReturn();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Incorrect");
				}
			}
			else//adaptive
			{
				Action a;
				Primary.CurrentResponse = strButton;
				if(Primary.CurrentStim.strDesiredResponse.ToLower()==strButton)
				{
					a = PrimaryAR.AddResponse(true,Primary.nCurrentLevel);
					nCorrect++;
					nR = 1;
					IncrementRight();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Correct");
				}
				else
				{
					a = PrimaryAR.AddResponse(false,Primary.nCurrentLevel);
					nR = 0;
					IncrementWrong();
					iwriter.WriteLine("{0},{1},{2}",strButton,Primary.CurrentStim.strDesiredResponse,"Incorrect");
				}
				if(a==Action.Complete)
				{
					PrimaryComplete();
					return;
				}
				if(a==Action.NStepSizeChange||a==Action.PStepSizeChange)
				{
					//Go to next step size
					Primary.CalcLevels.Clear();
					Primary.nStepType++;
					Primary.nStepSize = mainmenu.def.nSecondaryStep;
					
				}
				if(a==Action.PositiveReturn || a==Action.PStepSizeChange)
					PositiveReturn();
				else if(a==Action.NegativeReturn|| a==Action.NStepSizeChange)
					NegativeReturn();
				else if(a==Action.None)
				{
					Primary.strAction = "NONE";
					WriteResult();
				}
			}
			//update the game
			if(nCount>=nDelay)
			{
				if(mainmenu.def.nGameDelayType==0)
				{
					for(int kk=0;kk<nCorrect;kk++)
						StepGame();
				}
				else
					StepGame();
				nCount=0;
				nCorrect=0;
			}
			game.Update();
			//Do we stop here?
			if(mainmenu.def.nNumberOfTrials==this.nCompleted)
			{
				bGlobalDone = true;
				player.Stop();
				this.WriteSummary();
				MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
			}
			//set button colors
			foreach(Button b in mainmenu.def.Buttons)
				b.BackColor = this.BackColor;
			Next();
			/*if(mainmenu.def.bWaitForNextButton==false)
			{
				timer2.Start();
			}
			else
			{
				this.bButtons = true;
				bWaiting = true;
			}*/
		}
		
		private void PrimaryComplete()
		{
			//May want to EvaluateSecondary here,
			//if you want to change the secondary, but keep the same primary
			Primary.strAction = "C";
			WriteResult();
			//nCount++;
			/*if(PrimaryAR.LastResponse==true)
			{
				nCorrect++;
			}*/
			if(nCount>=nDelay)
			{
				for(int kk=0;kk<nCorrect;kk++)
					StepGame();
				nCount=0;
				nCorrect=0;
			}
			bool bDone = false;
			UpdateList2();
			if(mainmenu.def.nAdaptType==3)
			{
				//get next secondary, if any.  if none, we are done
				if(mainmenu.def.strSecondaryOrder=="randominterval" ||
					mainmenu.def.strSecondaryOrder=="randomtrial"  ||
					mainmenu.def.strSecondaryOrder=="inorder"||
					bSecondary==false)
					bDone=true;
				else if(GetSecondaryStim()==true)
				{
					//reset Primary variables
					Primary.nCurrentStim = -1;
					PrimaryAR.Clear();
					PrimaryAR.SetMethod(Primary.CurrentStim.nMethod);
					Secondary.Levels.Clear();
					Secondary.CalcLevels.Clear();
					Secondary.nCurrentLevel = Secondary.CurrentStim.nOrigin;
					Primary.nStepType = 1;
					Primary.nStepSize = mainmenu.def.nPrimaryStep;
					Primary.nTrialCount = 0;
					Primary.bZeroed = false;
					GetPrimaryStim();
					timer2.Start();
				}
				else
					bDone = true;
			}
			else if(GetPrimaryStim()==true)
			{
				if(mainmenu.def.nAdaptType==2)
				{
					//if we are running secondary adaptive,
					//we have finished 1 threshold, and are starting another
					//reset the pertinent properties in Secondary
					PrimaryAR.Clear();
					PrimaryAR.SetMethod(Primary.CurrentStim.nMethod);
					Secondary.Levels.Clear();
					Secondary.CalcLevels.Clear();
					Secondary.nCurrentLevel = Secondary.CurrentStim.nOrigin;
					Primary.nStepType = 1;
					Primary.nStepSize = mainmenu.def.nPrimaryStep;
					Primary.nTrialCount = 0;
					Primary.bZeroed = false;
				}
				timer2.Start();
			}
			else
			{
				//if there is secondary, evaluate and continue
				if(Secondary.nTotalStims>0)
				{
					if(mainmenu.def.nAdaptType==2)
					{
						//Reset the primaries, and get the next Secondary
						if(GetSecondaryStim()==false)
							bDone = true;
						else
						{
							Primary.nCurrentStim=-1;
							if(mainmenu.def.bRandom==true)
							{
								RandomizePrimary();
							}
							timer2.Start();
							return;
						}
					}
					else//nAdaptType==1
					{
						//get next secondary, if any.  if none, we are done
						if(mainmenu.def.strSecondaryOrder=="randominterval" ||
							mainmenu.def.strSecondaryOrder=="randomtrial"  ||
							mainmenu.def.strSecondaryOrder=="inorder" )
							bDone=true;
						else if(GetSecondaryStim()==true)
						{
							//reset Primary variables
							Primary.nCurrentStim = -1;
							GetPrimaryStim();
							timer2.Start();
						}
						else
							bDone = true;
					}
				}
				else
					bDone = true;
			}
			if(bDone==true)
			{
				//else we are done
				//					WriteResults();
				bGlobalDone = true;
				player.Stop();
				this.WriteSummary();
				MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
					
			}
		}
		
		private void PositiveReturn()
		{
			//if bBandwith is true
			//increase bandwidth on positve response
			//else increase bandwidth on negative response
			Primary.strAction = "+";
			WriteResult();
			if(mainmenu.def.nAdaptType>0)
			{
				if(Primary.AdaptType==AdaptiveTypes.Level)
				{
					if(bBandwidth==true)
						IncreaseLevel();
					else
						DecreaseLevel();
				}
				else if(Primary.AdaptType==AdaptiveTypes.LowPass)
				{
					if(bBandwidth==true)
						IncreaseCutoff();
					else
						DecreaseCutoff();
					ProcessPrimaryStim();
				}
				else if(Primary.AdaptType==AdaptiveTypes.HiPass)
				{
					if(bBandwidth==true)
						DecreaseCutoff();
					else
						IncreaseCutoff();
					ProcessPrimaryStim();
				}
				else if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
				{
					if(bBandwidth==true)
						DecreaseCutoff();//increase total bandwidth
					else
						IncreaseCutoff();//decrease total bandwidth
					ProcessPrimaryStim();
				}
				else if(Primary.AdaptType==AdaptiveTypes.MFile)
				{
				}
				
			}
			else
			{
				bool bDone = false;
				Primary.CurrentStim.Responses = new ArrayList();
				Primary.CurrentStim.Responses.Add(true);
				if(this.GetPrimaryStim()==false)
				{
					if(mainmenu.def.strSecondaryOrder=="Random"&&mainmenu.def.bRandom==true)
						bDone=true;
					else if(Secondary.nTotalStims>0)
					{
						//get next secondary, if any.  if none, we are done
						if(GetSecondaryStim()==true)
						{
							if(mainmenu.def.bRandom==true)
								RandomizePrimary();
							//reset Primary variables
							Primary.nCurrentStim = -1;
							GetPrimaryStim();
							timer2.Start();
						}
						else
							bDone=true;
					}
					else
						bDone = true;
					if(bDone==true)
					{
						player.Stop();
						this.Update();
						bGlobalDone = true;
						this.WriteSummary();
						MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
					}
				}
			}

			Primary.bCurrentResponse = true;
		}
		private void NegativeReturn()
		{
			//if bBandwith is true
			//increase bandwidth on positve response
			//else increase bandwidth on negative response
			Primary.strAction = "-";
			WriteResult();
			if(mainmenu.def.nAdaptType>0)
			{
					if(Primary.AdaptType==AdaptiveTypes.Level)
					{
						if(bBandwidth==true)
							DecreaseLevel();
						else
							IncreaseLevel();
					}
					else if(Primary.AdaptType==AdaptiveTypes.LowPass||Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
					{
						if(bBandwidth==true)
							DecreaseCutoff();
						else
							IncreaseCutoff();
						ProcessPrimaryStim();
					}
					else if(Primary.AdaptType==AdaptiveTypes.HiPass)
					{
						if(bBandwidth==true)
							IncreaseCutoff();
						else
							DecreaseCutoff();
						ProcessPrimaryStim();
					}
					else if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
					{
						if(bBandwidth==true)
							IncreaseCutoff();//decrease total bandwidth
						else
							DecreaseCutoff();//increase total bandwidth
						ProcessPrimaryStim();
					}
					else if(Primary.AdaptType==AdaptiveTypes.MFile)
					{
					}
			}
			else
			{
				bool bDone = false;
				Primary.CurrentStim.Responses = new ArrayList();
				Primary.CurrentStim.Responses.Add(false);
				if(this.GetPrimaryStim()==false)
				{
					if(mainmenu.def.strSecondaryOrder=="Random"&&mainmenu.def.bRandom==true)
						bDone=true;
					else if(Secondary.nTotalStims>0)
					{
						//get next secondary, if any.  if none, we are done
						if(GetSecondaryStim()==true)
						{
							if(mainmenu.def.bRandom==true)
								RandomizePrimary();
							//reset Primary variables
							Primary.nCurrentStim = -1;
							GetPrimaryStim();
							timer2.Start();
						}
						else
							bDone=true;
					}
					else
						bDone = true;
					if(bDone==true)
					{
						this.Update();
						bGlobalDone = true;
						player.Stop();
						this.WriteSummary();
						MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
					}
				}
			}
			Primary.bCurrentResponse = false;
		}

		private void StepGame()
		{
			//bButtons = false;
			if(game.Step()==false)
			{
				Primary.nCurrentGame++;
				if(Primary.nCurrentGame==mainmenu.def.Feedback.Count)
					Primary.nCurrentGame=0;
				game.SetupGame(mainmenu.def.strFeedbackDir,(string) mainmenu.def.Feedback[Primary.nCurrentGame]);		
			}
		}
		private void DecreaseLevel()
		{	
			//This function was called DecreaseLevel in legacy code

			//Don't let the signal go higher than
			//CalDb, or MaxLevel, whichever is less.
			int nMax = (int) mainmenu.CalDb;
			if(mainmenu.CalDb>mainmenu.def.nMaxLevel)
				nMax = mainmenu.def.nMaxLevel;
			
			if(mainmenu.def.nAdaptType==1||mainmenu.def.nAdaptType==3)
			{
				Primary.nCurrentLevel += Primary.nStepSize;
				if(Primary.CurrentStim is ComplexStim)
				{
					#region Complex
					ComplexStim cs = (ComplexStim) Primary.CurrentStim;
					if(cs.AtMax(Primary.nCurrentLevel,nMax))
					{
						Primary.nCurrentLevel -= Primary.nStepSize;
						if(Primary.Levels.Count>2)
						{
							if(((int)Primary.Levels[Primary.Levels.Count-2]==Primary.nCurrentLevel) && ((int)Primary.Levels[Primary.Levels.Count-3]==Primary.nCurrentLevel))
							{
								for(int k=0;k<Primary.CalcLevels.Count;k++)
									Primary.CalcLevels[k] = Primary.nCurrentLevel;
								PrimaryComplete();
							}//fi -15
						}
					}
					#endregion
				}
				if(Primary.nCurrentLevel> nMax)
				{
					Primary.nCurrentLevel= nMax;
					if(Primary.Levels.Count>2)
					{
						if(((int)Primary.Levels[Primary.Levels.Count-2]== nMax) && ((int)Primary.Levels[Primary.Levels.Count-3]== nMax))
						{
							for(int k=0;k<Primary.CalcLevels.Count;k++)
								Primary.CalcLevels[k] = nMax+10;
							PrimaryComplete();
						}
					}
				}
			}
			else if(mainmenu.def.nAdaptType==2)
			{
				Secondary.nCurrentLevel += Primary.nStepSize;
				if(Secondary.CurrentStim is ComplexStim)
				{
					#region Complex
					ComplexStim cs = (ComplexStim) Secondary.CurrentStim;
					if(cs.AtMax(Secondary.nCurrentLevel,nMax))
					{
						Secondary.nCurrentLevel -= Primary.nStepSize;
						if(Secondary.Levels.Count>2)
						{
							if(((int)Secondary.Levels[Secondary.Levels.Count-2]==Secondary.nCurrentLevel) && ((int)Secondary.Levels[Secondary.Levels.Count-3]==Secondary.nCurrentLevel))
							{
								for(int k=0;k<Secondary.CalcLevels.Count;k++)
									Secondary.CalcLevels[k] = Secondary.nCurrentLevel;
								PrimaryComplete();
							}//fi -15
						}
					}
					#endregion
				}
				if(Secondary.nCurrentLevel> nMax)
				{
					Secondary.nCurrentLevel= nMax;
					if(Secondary.Levels.Count>2)
					{
						if(((int)Secondary.Levels[Secondary.Levels.Count-2]== nMax) && ((int)Secondary.Levels[Secondary.Levels.Count-3]== nMax))
						{
							for(int k=0;k<Secondary.CalcLevels.Count;k++)
								Secondary.CalcLevels[k] = nMax+10;
							PrimaryComplete();
						}
					}
				}
			}
		}
		private void IncreaseLevel()
		{
			
			if(mainmenu.def.nAdaptType==1||mainmenu.def.nAdaptType==3)
			{
				Primary.nCurrentLevel -= Primary.nStepSize;
				if(Primary.CurrentStim is ComplexStim)
				{
					#region Complex
					ComplexStim cs = (ComplexStim) Primary.CurrentStim;
					if(cs.AtMin(Primary.nCurrentLevel,-20))
					{
						Primary.nCurrentLevel += Primary.nStepSize;
						if(Primary.Levels.Count>2)
						{
							if(((int)Primary.Levels[Primary.Levels.Count-2]==Primary.nCurrentLevel) && ((int)Primary.Levels[Primary.Levels.Count-3]==Primary.nCurrentLevel))
							{
								for(int k=0;k<Primary.CalcLevels.Count;k++)
									Primary.CalcLevels[k] = Primary.nCurrentLevel;
								PrimaryComplete();
							}//fi -15
						}
					}
					#endregion
				}
				else if(Primary.nCurrentLevel<=-20)
				{
					Primary.nCurrentLevel = -15;
					if(Primary.Levels.Count>2)
					{
						if(((int)Primary.Levels[Primary.Levels.Count-2]==-15) && ((int)Primary.Levels[Primary.Levels.Count-3]==-15))
						{
							for(int k=0;k<Primary.CalcLevels.Count;k++)
								Primary.CalcLevels[k] = -15;
							PrimaryComplete();
						}//fi -15
					}
				}//fi - 20
			}
			else if(mainmenu.def.nAdaptType==2)
			{
				Secondary.nCurrentLevel -= Primary.nStepSize;
				if(Secondary.CurrentStim is ComplexStim)
				{
					#region Complex
					ComplexStim cs = (ComplexStim) Secondary.CurrentStim;
					if(cs.AtMin(Secondary.nCurrentLevel,-20))
					{
						Secondary.nCurrentLevel += Primary.nStepSize;
						if(Secondary.Levels.Count>2)
						{
							if(((int)Secondary.Levels[Secondary.Levels.Count-2]==Secondary.nCurrentLevel) && ((int)Secondary.Levels[Secondary.Levels.Count-3]==Secondary.nCurrentLevel))
							{
								for(int k=0;k<Secondary.CalcLevels.Count;k++)
									Secondary.CalcLevels[k] = Secondary.nCurrentLevel;
								PrimaryComplete();
							}//fi -15
						}
					}
					#endregion
				}
				else if(Secondary.nCurrentLevel<=-20)
				{
					Secondary.nCurrentLevel = -15;
					if(Secondary.Levels.Count>2)
					{
						if(((int)Secondary.Levels[Secondary.Levels.Count-2]==-15) && ((int)Secondary.Levels[Secondary.Levels.Count-3]==-15))
						{
							for(int k=0;k<Secondary.CalcLevels.Count;k++)
								Secondary.CalcLevels[k] = -15;
							PrimaryComplete();
						}//fi -15
					}
				}//fi - 20
			}
		}
		
		private void DecreaseCutoff()
		{
			double exp = 1.0/Primary.nStepSize;
			double dd = Math.Pow(2.0,exp);
			double d = ((double)Primary.nCurrentCutoff)/dd;
			Primary.nCurrentCutoff = (int) d;
			if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
			{
				d = ((double)Primary.F2)*dd;
				Primary.F2 = (int) d;
			}
			ProcessPrimaryStim();
		}
		private void IncreaseCutoff()
		{
			double exp = 1.0/Primary.nStepSize;
			double dd = Math.Pow(2.0,exp);
			double d = ((double)Primary.nCurrentCutoff)*dd;
			Primary.nCurrentCutoff = (int) d;
			if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
			{
				d = ((double)Primary.F2)/dd;
				Primary.F2 = (int) d;
			}
			ProcessPrimaryStim();
		}
		
		private bool ProcessPrimaryStim()
		{
			//no longer considered active
			return false;
			/*Stim s = Primary.CurrentStim;
			//Load the wav into MatLab
			bool b;
			string str = string.Format("[y,Fs] = wavread('{0}');",mainmenu.def.strStimDirectory+"\\"+s.strFile);
			b = mat.Evaluate(str);
			
			if(b==true)
			{
				if(Primary.AdaptType==AdaptiveTypes.LowPass)
				{
					str = string.Format("StarFilter('lowpass',{0},{1},0,{2},y);",
						44100,
						Primary.nCurrentCutoff,
						mainmenu.def.nPrimaryFilterOrder);
					
				}
				else if(Primary.AdaptType==AdaptiveTypes.HiPass)
				{
					str = string.Format("StarFilter('hipass',{0},{1},0,{2},y);",
						44100,
						Primary.nCurrentCutoff,
						mainmenu.def.nPrimaryFilterOrder);
				}
				else if(Primary.AdaptType==AdaptiveTypes.BandPass||Primary.AdaptType==AdaptiveTypes.BandStop)
				{
					if(Primary.AdaptType==AdaptiveTypes.BandPass)
					{
						str = string.Format("StarFilter('bandpass',{0},{1},{3},{2},y);",
							44100,
							Primary.nCurrentCutoff,
							mainmenu.def.nPrimaryFilterOrder,
							Primary.F2);
					}
					else
					{
						str = string.Format("StarFilter('bandstop',{0},{1},{3},{2},y);",
							44100,
							Primary.nCurrentCutoff,
							mainmenu.def.nPrimaryFilterOrder,
							Primary.F2);
					}

				}
				else if(Primary.AdaptType==AdaptiveTypes.MFile)
				{
				}
				b = mat.Evaluate(str);
				if(b==true)
				{
					FileInfo f = new FileInfo("c:\\tempwav.wav");
					player.Signals[1].WaveFile(f,mainmenu.MaxAmplitude,s.strEar,false,s.AmpType);
				}
			}
			return b;*/
		}

	
		/// <summary>
		/// Member to evaluate the status of the secondary
		/// during a Secondary Adaptive Situation.
		/// EVERYTHING for altering and restarting the secondary
		/// must be done here.
		/// </summary>
		private void EvaluateSecondary()
		{
			//Determine positive or negative
			//evaluate positive or negative
			//alter secondary stimulus
			//or
			//move to next secondary stimulus
			//or
			//done

			//If altering secondary stimulus, you may need to reset values on the Primary stimulus

		}

		
		private void UpdateList2()
		{
			if(mainmenu.def.nAdaptType>0)
			{
				//Adaptive
				float f=0.0f;
				if(mainmenu.def.nAdaptType==2)
				{
					for(int k=0;k<Secondary.CalcLevels.Count;k++)
					{
						f+=(int)Secondary.CalcLevels[Secondary.CalcLevels.Count-1-k];
					}
					if(Secondary.CalcLevels.Count==0)
					{
						int nMax = (int) mainmenu.CalDb;
						if(mainmenu.CalDb>mainmenu.def.nMaxLevel)
							nMax = mainmenu.def.nMaxLevel;
						Secondary.CurrentStim.fThreshold = nMax;
					}
					else
						Secondary.CurrentStim.fThreshold = f/Secondary.CalcLevels.Count;
				}
				else
				{
					for(int k=0;k<Primary.CalcLevels.Count;k++)
					{
						f+=(int)Primary.CalcLevels[Primary.CalcLevels.Count-1-k];
					}
					if(Primary.CalcLevels.Count==0)
					{
						int nMax = (int) mainmenu.CalDb;
						if(mainmenu.CalDb>mainmenu.def.nMaxLevel)
							nMax = mainmenu.def.nMaxLevel;
						Primary.CurrentStim.fThreshold = nMax;
					}
					else
						Primary.CurrentStim.fThreshold = f/Primary.CalcLevels.Count;
				}
				ListViewItem i = new ListViewItem();
				int x = 0;
				foreach(string str in mainmenu.def.listRes)
				{
					if(x==0)
						i.Text = GetField(str);
					else
						i.SubItems.Add(GetField(str));
					x++;
				}
				listView2.Items.Add(i);	
				i.Selected=true;
				listView2.EnsureVisible(i.Index);
			}
			else
			{
				//Fixed
				foreach(Stat s in listStats)
				{
					if(s.strPrimary.Length>0)
					{
						if(s.strPrimary!=GetField("primarystim"))
							continue;
					}
					if(s.strSecondary.Length>0)
					{
						if(s.strSecondary!=GetField("secondarystim"))
							continue;
					}
					if(s.strStimCat.Length>0)
					{
						if(s.strStimCat!=GetField("stimcat"))
							continue;
					}
					if(s.strEar.Length>0)
					{
						if(s.strEar!=GetField("ear"))
							continue;
					}
					if(s.strAltCat.Length>0)
					{
						if(s.strAltCat!=GetField("altcat"))
							continue;
					}
					s.Total++;
					if(s.strResponse.Length>0)
					{
						if(s.strResponse!=GetField("response"))
							continue;
					}
					if(nR==1)
						s.Correct++;
					s.Freq++;
					//break;
				}
				listView2.Items.Clear();
				foreach(Stat s in listStats)
				{
					ListViewItem i = new ListViewItem();
					int x =0;
					foreach(string str in mainmenu.def.listRes)
					{
						if(str!="perf"&&str!="freq")
						{
							if(x==0)
								i.Text = GetField(s,str);
							else
								i.SubItems.Add(GetField(s,str));
							x++;
						}
					}
					if((string)mainmenu.def.listRes[0]=="perf")
					{
						if(s.Freq!=0)
						{
							double d = ((double)s.Correct/(double)s.Freq)*100.0;
							i.SubItems.Add(d.ToString("###.0"));
						}
						else
							i.SubItems.Add("0");
					}
					else
					{
						if(s.Total!=0)
						{
							double d = ((double)s.Freq/(double)s.Total)*100.0;
							i.SubItems.Add(d.ToString("###.0"));
						}
						else
							i.SubItems.Add("0");
					}
					
					listView2.Items.Add(i);
					//	i.Selected=true;
					//	listView1.EnsureVisible(i.Index);
				}

			}
		}
		private void WriteStart()
		{
			output = new StreamWriter(outfile.ToString(),true);
			output.WriteLine("%STAR RESULTS");
			output.WriteLine(string.Empty);
			output.WriteLine("%SUBJECT DATA");
			output.WriteLine("%"+mainmenu.txtName.Text);
			output.WriteLine("%"+mainmenu.txtBirth.Text);
			output.WriteLine("%"+mainmenu.cmbGender.Text);
			output.WriteLine("%"+mainmenu.txtGroup.Text);
			output.WriteLine("%"+mainmenu.txtId.Text);
			output.WriteLine(string.Empty);
			output.WriteLine("%Definition File: "+mainmenu.def.strInitFile);
			if(mainmenu.txtFreqShape.Text.Length>0)
			{
				try
				{
					output.WriteLine("%FreqShape File: "+mainmenu.txtFreqShape.Text);
					output.WriteLine("%%%%%FreqShape Params%%%%%");
					StreamReader sr = new StreamReader(mainmenu.txtFreqShape.Text);
					output.Write(sr.ReadToEnd());
					output.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%");
					sr.Close();
				}
				catch(Exception)
				{
				}
			}
			output.WriteLine("%StimuliDirectory: "+mainmenu.def.strStimDirectory);
			output.WriteLine("%"+DateTime.Now.ToShortDateString());
			output.WriteLine("%"+DateTime.Now.ToShortTimeString());
			output.WriteLine(string.Empty);
			output.WriteLine("Calibration: "+mainmenu.GetCal());
			output.WriteLine(string.Empty);
			if(mainmenu.txtBirth.Text.Length>0)
			{
				try
				{
					DateTime dtBirth = DateTime.Parse(mainmenu.txtBirth.Text);
					
					TimeSpan sp = DateTime.Now.Subtract(dtBirth);
					double age = sp.Days/365.25;
					int yrs = (int) age;
					int mos = (int) ((age-yrs)*12);
					output.WriteLine("%"+yrs.ToString() + ";" + mos.ToString());
				}
				catch(Exception){}
			}
			output.WriteLine(string.Empty);

			output.WriteLine("%"+"STIMULI");
			output.WriteLine("%"+"Primary");
			foreach(Stim s in mainmenu.def.PrimaryStims)
			{
				if(s is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) s;
					output.WriteLine("ComplexStim {0}  {1}",cs.nTotalLength,cs.nNumberOfStims);
					foreach(Stim sub in cs.listStims)
					{
						output.WriteLine("Type: {0} Freq: {1} Phase: {2} Start: {3} Stop: {4} Adapt: {5}",
							sub.strType,sub.nFreq,sub.nInitialPhase,sub.nStart,sub.nStop,sub.bAdapt);
					}

				}
				else
				{
					output.WriteLine("%"+s.strFile);
				}
			}
			output.WriteLine("%"+"Secondary");
			foreach(Stim s in mainmenu.def.SecondaryStims)
			{
				if(s is ComplexStim)
				{
					ComplexStim cs = (ComplexStim) s;
					output.WriteLine("ComplexStim {0}  {1}",cs.nTotalLength,cs.nNumberOfStims);
					foreach(Stim sub in cs.listStims)
					{
						output.WriteLine("Type: {0} Freq: {1} Phase: {2} Start: {3} Stop: {4} Adapt: {5}",
							sub.strType,sub.nFreq,sub.nInitialPhase,sub.nStart,sub.nStop,sub.bAdapt);
					}

				}
				else
				{
					output.WriteLine("%"+s.strFile);
				}
			}
			output.WriteLine(string.Empty);
			output.WriteLine("%REPITITIONS");
			output.WriteLine("%"+mainmenu.def.nReps.ToString());
			if(mainmenu.def.nAdaptType>0)
			{
				output.WriteLine("%ADAPTIVE");
				output.WriteLine("%"+mainmenu.def.PrimaryAdapt.ToString());
				if(mainmenu.def.nAdaptType==1)
					output.WriteLine("%Primary");
				else if(mainmenu.def.nAdaptType==2)
					output.WriteLine("%Secondary");
				else if(mainmenu.def.nAdaptType==3)
					output.WriteLine("%Adapt Across Primaries");
			}
			else
				output.WriteLine("%FIXED");

			output.WriteLine(string.Empty);
			output.WriteLine("%RAW DATA");
			if(mainmenu.def.nAdaptType>0)
			{
				output.WriteLine("% Primary Stim,PresLevel,SecStim,CornerFreq,StimCat,Response,Correct,Action,Method,Ear");			
			}
			else
				output.WriteLine("% Primary Stim,PresLevel,SecStim,SecStimLevel,AltCat,StimCat,Response,Correct,Action,Method,Ear");

			output.Flush();
			output.Close();
		}
		private void WriteResult()
		{
			output = new StreamWriter(outfile.ToString(),true);
			//Primary Stim \t LevelFreq \t Secondary Stim \t 
			//Response \t Correct \t Desired \t Action \t Method \t Ear
			string strStim;
			if(Primary.CurrentStim is ComplexStim)
			{
				strStim = "Complex";
			}
			else if(Primary.CurrentStim.nFreq>0)
				strStim = Primary.CurrentStim.nFreq.ToString();
			else
				strStim = Primary.CurrentStim.strFile;
			int nEar = 0;
			if(Primary.CurrentStim.strEar=="right")
				nEar=1;
			else if(Primary.CurrentStim.strEar=="left")
				nEar=2;
			else if(Primary.CurrentStim.strEar=="both")
				nEar=3;

			if(strSec.Length<=0)
			{
				if(Secondary.CurrentStim==null)
					strSec = "NONE";
				else if(Secondary.CurrentStim is ComplexStim)
				{
					strSec = "Complex";
				}
				else if(Secondary.CurrentStim.strFile.Length>0)
					strSec = Secondary.CurrentStim.strFile;
				else
					strSec = Secondary.CurrentStim.strType+ " " +Secondary.CurrentStim.nFreq.ToString();
				strSec +=","+Secondary.nCurrentLevel.ToString();
			}
			
			string str;
			string strCurrentLevel = Primary.nCurrentLevel.ToString();
			if(Primary.CurrentStim.AmpType==AmplificationTypes.None)
				strCurrentLevel = "?";

			ListViewItem i = new ListViewItem();
			i.Text = strStim;
			i.SubItems.Add(strCurrentLevel);
			i.SubItems.Add(strSec);
			i.SubItems.Add(Secondary.nCurrentLevel.ToString());
			if(mainmenu.def.nAdaptType>0)
			{
				str = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
					strStim, strCurrentLevel, strSec,Primary.nCurrentCutoff,
					Primary.CurrentStim.strDesiredResponse,Primary.CurrentResponse,
					nR,Primary.strAction,Primary.CurrentStim.nMethod, nEar);
				i.SubItems.Add(Primary.nCurrentCutoff.ToString());
			}
			else
			{
				str = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
					strStim, strCurrentLevel, strSec,
					Primary.CurrentStim.strInfo,Primary.CurrentStim.strDesiredResponse,
					Primary.CurrentResponse,nR,
					9,9, nEar);
				i.SubItems.Add(Primary.CurrentStim.strInfo);
			}
			output.WriteLine(str);
			output.Flush();
			output.Close();

			listView1.BeginUpdate();
			i.SubItems.Add(Primary.CurrentStim.strDesiredResponse);
			i.SubItems.Add(Primary.CurrentResponse);
			i.SubItems.Add(nR.ToString());
			if(mainmenu.def.nAdaptType>0)
			{
				i.SubItems.Add(Primary.strAction);
				i.SubItems.Add(Primary.CurrentStim.nMethod.ToString());
			}
			else
			{
				i.SubItems.Add("9");
				i.SubItems.Add("9");
			}
			i.SubItems.Add(nEar.ToString());
			listView1.Items.Add(i);
			i.Selected=true;
			listView1.EnsureVisible(i.Index);
			listView1.EndUpdate();
			
			if(mainmenu.def.nAdaptType==0)
			{
				UpdateList2();
			}
			strSec = string.Empty;

		}

		private void WriteCatch(int Correct)
		{
			output = new StreamWriter(outfile.ToString(),true);
			//Primary Stim \t LevelFreq \t Secondary Stim \t 
			//Response \t Correct \t Desired \t Action \t Method \t Ear
			string str;
			ListViewItem i = new ListViewItem();
			i.Text = "Catch Trial";
			i.SubItems.Add(string.Empty);
			i.SubItems.Add(string.Empty);
			if(mainmenu.def.nAdaptType>0)
			{
				str = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
					"CatchTrial", string.Empty, string.Empty,string.Empty,
					1,Correct,
					nR,string.Empty,string.Empty, string.Empty);
				i.SubItems.Add(string.Empty);
			}
			else
			{
				str = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9}",
					"CatchTrial", string.Empty, string.Empty,
					"CatchTrial",1,
					Correct,nR,
					9,9, string.Empty);
				i.SubItems.Add(Primary.CurrentStim.strInfo);
			}
			output.WriteLine(str);
			output.Flush();
			output.Close();

			listView1.BeginUpdate();
			i.SubItems.Add("1");
			i.SubItems.Add(Correct.ToString());
			i.SubItems.Add(nR.ToString());
			if(mainmenu.def.nAdaptType>0)
			{
				i.SubItems.Add(string.Empty);
				i.SubItems.Add(string.Empty);
			}
			else
			{
				i.SubItems.Add("9");
				i.SubItems.Add("9");
			}
			i.SubItems.Add(string.Empty);
			listView1.Items.Add(i);
			i.Selected=true;
			listView1.EnsureVisible(i.Index);
			listView1.EndUpdate();
		}
		private void btnSummary_Click(object sender, System.EventArgs e)
		{
			WriteSummary();
		}
		private void WriteSummary()
		{
			game.Finish();
			output = new StreamWriter(outfile.ToString(),true);
			output.WriteLine(string.Empty);
			output.WriteLine(string.Empty);
			ColumnHeader c;
			string str = "%";
			for(int x=0;x<listView2.Columns.Count;x++)
			{
				c = listView2.Columns[x];
				str+=c.Text+",";
			}
			ListViewItem i;
			str = listView2.Items.Count.ToString();
			output.WriteLine("{0} Items in list",str);
			for(int x=0;x<listView2.Items.Count;x++)
			{
				i = listView2.Items[x];
				str = "%";
				foreach(ListViewItem.ListViewSubItem si in i.SubItems)
				{
					str+=","+si.Text;
				}
				output.WriteLine(str);
			}
			output.WriteLine(string.Empty);
			output.WriteLine("Catches: " + Primary.nCatches.ToString());
			output.WriteLine("False Positives: " + Primary.nFalse.ToString());
			TimeSpan s = DateTime.Now-dtStarted;
			str = string.Format("%Elapsed Time: {0}:{1}:{2}",s.Hours,s.Minutes,s.Seconds);
			output.WriteLine(str);
			output.Flush();
			output.Close();
			Summary = true;
		}


		//Investigator Screen Stuff
		private void ShowPrimaryStim(Stim s)
		{
			if(s.strFile.Length>0)
			{
				FileInfo f = new FileInfo(s.strFile);
				this.txtPrimary.Text = f.Name;
			}
			else if(s is ComplexStim)
			{
				txtPrimary.Text = "Complex Stim";
			}
			else
				this.txtPrimary.Text = s.nFreq.ToString();
			this.Update();
		}
		private void ShowSecondaryStim(Stim s)
		{
			if(s.strFile.Length>0)
			{
				FileInfo f = new FileInfo(s.strFile);
				this.txtSecondary.Text = f.Name;
			}
			else if(s is ComplexStim)
			{
				txtSecondary.Text = "Complex Stim";
			}
			else
				this.txtSecondary.Text = s.strType + " " +s.nFreq.ToString()+ " " + Secondary.nCurrentLevel.ToString()+"dB";
		}
		private void ShowPrimaryLevel(int nLevel)
		{
			if(Primary.CurrentStim.AmpType!=AmplificationTypes.None)
				this.txtLevel.Text = nLevel.ToString();
			else
				txtLevel.Text = "?";
			if(PrimaryAR.Mode==0)//standard error
				this.txtStdErr.Text = PrimaryAR.standardError.ToString("###.00");
			else
				this.txtStdErr.Text = PrimaryAR.Reversals.ToString();
			
		}
		private void ShowTotal(int nTotal)
		{
			this.txtTotal.Text = nTotal.ToString();
			game.SetTotalGames(nTotal);
		}
		private void ShowStandardError()
		{
			if(PrimaryAR.Mode==0)//stopping on standard error
				this.txtStdErr.Text = PrimaryAR.standardError.ToString("###.00");
			else if(PrimaryAR.Mode==1)//stopping on number of reversals
				txtStdErr.Text = nReversals.ToString();
		}
		private void InitCompleted()
		{
			this.txtCurrent.Text = "0";
			nCompleted = 0;
			
			
		}
		private void IncrementCompleted()
		{
			nCompleted++;
			this.txtCurrent.Text = nCompleted.ToString();
			TimeSpan s = DateTime.Now-dtStarted;
			txtTime.Text = s.Hours.ToString() + ":" + s.Minutes.ToString() + ":" + s.Seconds.ToString();
			this.Update();

		}
		private void InitRight()
		{
			this.txtRight.Text = "0";
			nRight = 0;
		}
		private void IncrementRight()
		{
			nRight++;
			double pct = (100.0*nRight)/nCompleted;
			string str = string.Format("{0}     {1}%",nRight,pct.ToString("###.00"));
			this.txtRight.Text = str;

			pct = (100.0*nWrong)/nCompleted;
			str = string.Format("{0}     {1}%",nWrong,pct.ToString("###.00"));
			this.txtWrong.Text = str;
		}
		private void InitWrong()
		{
			txtWrong.Text = "0";
			nWrong = 0;
		}
		private void IncrementWrong()
		{
			nWrong++;
			double pct = (100.0*nWrong)/nCompleted;
			string str = string.Format("{0}     {1}%",nWrong,pct.ToString("###.00"));
			this.txtWrong.Text = str;

			pct = (100.0*nRight)/nCompleted;
			str = string.Format("{0}     {1}%",nRight,pct.ToString("###.00"));
			this.txtRight.Text = str;
		}


		private void btnReset_Click(object sender, System.EventArgs e)
		{
			timer.Stop();
			timer2.Stop();
			timer3.Stop();
			PrimaryAR.Clear();
			Primary.Levels.Clear();
			Primary.CalcLevels.Clear();
			Primary.nStepType = 1;
			Primary.nStepSize = mainmenu.def.nPrimaryStep;
			Primary.nCurrentLevel = (int) Primary.CurrentStim.nOrigin;
			Primary.nTrialCount = 0;
			Primary.bZeroed = false;
			Primary.CatchTrial = false;
			if(Primary.AdaptType==AdaptiveTypes.LowPass||Primary.AdaptType==AdaptiveTypes.HiPass)
			{
				Primary.nCurrentLevel = (int) Primary.CurrentStim.nOrigin;
				InitFilter();
				ProcessPrimaryStim();
			}
			timer2.Start();
		}

		private void btnSkip_Click(object sender, System.EventArgs e)
		{
			timer.Stop();
			timer2.Stop();
			timer3.Stop();
			Primary.strAction = "S";
			Primary.CurrentStim.bSkipped = true;
			WriteResult();
			UpdateList2();
			if(GetPrimaryStim()==true)
				timer2.Start();
			else
			{
				bool bDone = false;
				//if there is secondary, evaluate and continue
				if(Secondary.nTotalStims>0)
				{
					if(mainmenu.def.nAdaptType==2)
					{
						//Evaluate Secondary here to change the secondary, then run
						//through all of the primaries 
						EvaluateSecondary();
						return;
					}
					else
					{
						//get next secondary, if any.  if none, we are done
						if(GetSecondaryStim()==true)
						{
							//reset Primary variables
							Primary.nCurrentStim = -1;
							GetPrimaryStim();
							timer2.Start();
						}
						else
							bDone = true;
					}
				}
				else
					bDone = true;
				if(bDone==true)
				{
					//else we are done
					//					WriteResults();
					bGlobalDone = true;
					player.Stop();
					this.WriteSummary();
					MessageBox.Show(this,"Test Complete","Done",MessageBoxButtons.OK,MessageBoxIcon.Information);
				}
			}
		
		}

		private void btnPause_Click(object sender, System.EventArgs e)
		{
			this.sbStatus.Text="Status: Paused";
			timer.Stop();
			timer2.Stop();
			player.Stop();
			Paused = true;
			bButtons = false;
			this.btnPause.Text = "RESUME";
		}
		private void Continue()
		{
			if(Paused==true)
			{
				this.sbStatus.Text="Status: Ready";
				bButtons = true;
				Paused = false;
				this.btnPause.Text = "Pause";
				if(Primary.CurrentStim.strType=="PAUSE")
				{
					GetPrimaryStim();
					timer2.Start();
				}
				else
					timer.Start();
			}
		}

		
		private class Stat : object
		{
			public string strEar;
			public string strStimCat;
			public string strAltCat;
			public string strPrimary;
			public string strSecondary;
			public string strResponse;
			public double Perf;
			public double Freq;
			public int Total;
			public int Correct;

			public Stat()
			{
				strEar = string.Empty;
				strStimCat = string.Empty;
				strAltCat = string.Empty;
				strPrimary = string.Empty;
				strSecondary = string.Empty;
				strResponse = string.Empty;
				Perf = 0.0;
				Freq = 0.0;
				Total = 0;
				Correct = 0;
			}
		}

		private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			//lvwColumnSorter.bInteger = true;
			
			if ( e.Column == lvwColumnSorter.SortColumn )
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter.Order == SortOrder.Ascending)
				{
					lvwColumnSorter.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter.SortColumn = e.Column;
				lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.listView1.Sort();

		}

		private void listView2_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			//lvwColumnSorter2.bInteger = true;
			if ( e.Column == lvwColumnSorter.SortColumn )
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter2.Order == SortOrder.Ascending)
				{
					lvwColumnSorter2.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter2.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter2.SortColumn = e.Column;
				lvwColumnSorter2.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.listView2.Sort();

		}

		private void game_KeyEvt(object sender, KeyPressEventArgs e)
		{
			EventArgs ev = new EventArgs();
			switch(e.KeyChar)
			{
				case 'r':
				case 'R':
					btnReset_Click(sender,ev);
					break;
				case 's':
				case 'S':
					btnSkip_Click(sender,ev);
					break;
				case 'p':
				case 'P':
					btnPause_Click(sender, ev);
					break;
				case 'c':
				case 'C':
					Continue();
					break;
			}
		}
				
	}

	
}
