using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using System.Text;
using System.Collections.Specialized;

namespace HearingAidLab
{
	/// <summary>
	/// Summary description for PairedComparison.
	/// </summary>
	public class PairedComparison : System.Windows.Forms.Form
	{
		
		private string m_strFolderPath= String.Empty; // folder containing sound files
		private System.Windows.Forms.StatusBar sbStatus; // status bar
		private System.Windows.Forms.StatusBarPanel sbpFolder; //status showing folder
		public FileInfo outfile;
		public Form1 mainmenu;   // reference to main form
		ArrayList  lstEBW = new ArrayList();  // contains EBW filenames
		ArrayList  lstRBW = new ArrayList();  // contains RBW filenames
		ArrayList  lstFC  = new ArrayList();  // contains FC filenames
		ArrayList DoneCombination = new ArrayList(); // list of combinations already played
		System.Collections.Hashtable DC = new Hashtable();
		public StreamWriter output;
		private Run StimEBW;    
		private Run StimRBW;
		private Run StimFC;
		private Run Primary;
		private Run Secondary;
		public WaveLib.WavePlayer player = new WaveLib.WavePlayer();
		private Random R;
		private int iPlayCount=0;
		private DateTime dtStart;
		private DateTime LastPlayMoment;
		private bool bPaused = false;
		private bool bPlayInProgress = false;
		private bool bEnableCatchTrial;
		private int iTotCatchNum=0;
		private int iCatchTrialInterval=0;
		private bool bIsCatchTrial = false;// whether this run is a catch trial run
		private StarGame.GameForm pcGame;
	#region windows controls

		private System.Windows.Forms.TextBox txtStdErr;
		private System.Windows.Forms.TextBox txtTime;
		private System.Windows.Forms.TextBox txtSecondary;
		private System.Windows.Forms.TextBox txtLevel;
		private System.Windows.Forms.TextBox txtPrimary;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.ListView listView2;
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.TextBox txtTotalPresentation;
		private System.Windows.Forms.TextBox txtCompleted;
		private System.Windows.Forms.Button btnPause;
		private System.Windows.Forms.Button btnReset;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.ListView listView1;
		private System.Windows.Forms.TextBox txtRemaining;
	#endregion
		private System.Windows.Forms.Timer timerPlay; //Each tick plays a sound pair.
		private int PLAY_INTERVAL; //interval for timerPlay.sound-pair kicks off every this interval
		private int INTER_STIM_INTERVAL;
		
		private System.Windows.Forms.Button button2;
		private System.Windows.Forms.Button btnPlay;
		private System.Windows.Forms.Timer timerPulse;
		private System.Windows.Forms.Button btnGenReport;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.TextBox txtCatchTrials;
		private System.Windows.Forms.Button btnEditCatch;
		private System.Windows.Forms.TextBox txtCatchPC; // two sounds in a pair are seperated by this interval
		private System.ComponentModel.IContainer components;
		
		private int StimCount=0;//how many files on each stim category
		private int StimCategoryCount=0; // how many file category (=3: EBW,RBW,FC)
		private double CombinStims=0;
		public PairedComparison()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			if (player.Open() == false)
			{
				MessageBox.Show(this,"Unable to open sound card!","Audio Error",MessageBoxButtons.OK,MessageBoxIcon.Stop);
				return;
			}
			StimEBW = new Run();
			StimRBW = new Run();
			StimFC = new Run();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{   
			if(player.ibolArscRunning)return ;//dont close if file is being played.
			mainmenu.Show();
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			lstEBW.Clear();
			lstRBW.Clear();
			lstFC.Clear();
			if(output != null)
			{
				try
				{
					output.Flush();
					output.Close();
				}
				catch (Exception ) {} 
			}
			player.Stop();
			player.Close();
			DC.Clear();//hashtable
			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()
		{
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PairedComparison));
			this.sbStatus = new System.Windows.Forms.StatusBar();
			this.sbpFolder = new System.Windows.Forms.StatusBarPanel();
			this.btnPlay = new System.Windows.Forms.Button();
			this.txtStdErr = new System.Windows.Forms.TextBox();
			this.txtTime = new System.Windows.Forms.TextBox();
			this.txtSecondary = new System.Windows.Forms.TextBox();
			this.txtLevel = new System.Windows.Forms.TextBox();
			this.txtTotalPresentation = new System.Windows.Forms.TextBox();
			this.txtCompleted = new System.Windows.Forms.TextBox();
			this.txtPrimary = new System.Windows.Forms.TextBox();
			this.label9 = new System.Windows.Forms.Label();
			this.listView2 = new System.Windows.Forms.ListView();
			this.listView1 = new System.Windows.Forms.ListView();
			this.label8 = new System.Windows.Forms.Label();
			this.label5 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.label1 = new System.Windows.Forms.Label();
			this.btnPause = new System.Windows.Forms.Button();
			this.btnReset = new System.Windows.Forms.Button();
			this.label6 = new System.Windows.Forms.Label();
			this.txtRemaining = new System.Windows.Forms.TextBox();
			this.timerPlay = new System.Windows.Forms.Timer(this.components);
			this.button2 = new System.Windows.Forms.Button();
			this.timerPulse = new System.Windows.Forms.Timer(this.components);
			this.btnGenReport = new System.Windows.Forms.Button();
			this.label7 = new System.Windows.Forms.Label();
			this.txtCatchTrials = new System.Windows.Forms.TextBox();
			this.btnEditCatch = new System.Windows.Forms.Button();
			this.txtCatchPC = new System.Windows.Forms.TextBox();
			((System.ComponentModel.ISupportInitialize)(this.sbpFolder)).BeginInit();
			this.SuspendLayout();
			// 
			// sbStatus
			// 
			this.sbStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.sbStatus.Dock = System.Windows.Forms.DockStyle.None;
			this.sbStatus.Location = new System.Drawing.Point(8, 480);
			this.sbStatus.Name = "sbStatus";
			this.sbStatus.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
																						this.sbpFolder});
			this.sbStatus.ShowPanels = true;
			this.sbStatus.Size = new System.Drawing.Size(832, 24);
			this.sbStatus.TabIndex = 0;
			// 
			// btnPlay
			// 
			this.btnPlay.Location = new System.Drawing.Point(16, 248);
			this.btnPlay.Name = "btnPlay";
			this.btnPlay.Size = new System.Drawing.Size(72, 24);
			this.btnPlay.TabIndex = 1;
			this.btnPlay.Text = "Play";
			this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
			// 
			// txtStdErr
			// 
			this.txtStdErr.Location = new System.Drawing.Point(152, 88);
			this.txtStdErr.Name = "txtStdErr";
			this.txtStdErr.ReadOnly = true;
			this.txtStdErr.Size = new System.Drawing.Size(192, 20);
			this.txtStdErr.TabIndex = 36;
			this.txtStdErr.Text = "";
			// 
			// txtTime
			// 
			this.txtTime.Location = new System.Drawing.Point(152, 192);
			this.txtTime.Name = "txtTime";
			this.txtTime.ReadOnly = true;
			this.txtTime.Size = new System.Drawing.Size(192, 20);
			this.txtTime.TabIndex = 39;
			this.txtTime.TabStop = false;
			this.txtTime.Text = "";
			// 
			// txtSecondary
			// 
			this.txtSecondary.Location = new System.Drawing.Point(152, 40);
			this.txtSecondary.Name = "txtSecondary";
			this.txtSecondary.ReadOnly = true;
			this.txtSecondary.Size = new System.Drawing.Size(192, 20);
			this.txtSecondary.TabIndex = 34;
			this.txtSecondary.Text = "";
			// 
			// txtLevel
			// 
			this.txtLevel.Location = new System.Drawing.Point(152, 64);
			this.txtLevel.Name = "txtLevel";
			this.txtLevel.ReadOnly = true;
			this.txtLevel.Size = new System.Drawing.Size(192, 20);
			this.txtLevel.TabIndex = 35;
			this.txtLevel.Text = "";
			// 
			// txtTotalPresentation
			// 
			this.txtTotalPresentation.Location = new System.Drawing.Point(152, 112);
			this.txtTotalPresentation.Name = "txtTotalPresentation";
			this.txtTotalPresentation.ReadOnly = true;
			this.txtTotalPresentation.Size = new System.Drawing.Size(192, 20);
			this.txtTotalPresentation.TabIndex = 37;
			this.txtTotalPresentation.Text = "";
			// 
			// txtCompleted
			// 
			this.txtCompleted.Location = new System.Drawing.Point(152, 136);
			this.txtCompleted.Name = "txtCompleted";
			this.txtCompleted.ReadOnly = true;
			this.txtCompleted.Size = new System.Drawing.Size(56, 20);
			this.txtCompleted.TabIndex = 38;
			this.txtCompleted.Text = "";
			// 
			// txtPrimary
			// 
			this.txtPrimary.Location = new System.Drawing.Point(152, 16);
			this.txtPrimary.Name = "txtPrimary";
			this.txtPrimary.ReadOnly = true;
			this.txtPrimary.Size = new System.Drawing.Size(192, 20);
			this.txtPrimary.TabIndex = 33;
			this.txtPrimary.Text = "";
			// 
			// label9
			// 
			this.label9.Location = new System.Drawing.Point(8, 88);
			this.label9.Name = "label9";
			this.label9.Size = new System.Drawing.Size(130, 23);
			this.label9.TabIndex = 44;
			this.label9.Text = "StdErr:";
			this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// listView2
			// 
			this.listView2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
			this.listView2.FullRowSelect = true;
			this.listView2.Location = new System.Drawing.Point(352, 224);
			this.listView2.Name = "listView2";
			this.listView2.Size = new System.Drawing.Size(480, 240);
			this.listView2.TabIndex = 43;
			this.listView2.View = System.Windows.Forms.View.Details;
			// 
			// listView1
			// 
			this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
			this.listView1.FullRowSelect = true;
			this.listView1.Location = new System.Drawing.Point(352, 16);
			this.listView1.Name = "listView1";
			this.listView1.Size = new System.Drawing.Size(480, 200);
			this.listView1.TabIndex = 42;
			this.listView1.View = System.Windows.Forms.View.Details;
			// 
			// label8
			// 
			this.label8.Location = new System.Drawing.Point(8, 192);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(130, 23);
			this.label8.TabIndex = 40;
			this.label8.Text = "Elapsed Time:";
			this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label5
			// 
			this.label5.Location = new System.Drawing.Point(8, 136);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(130, 23);
			this.label5.TabIndex = 30;
			this.label5.Text = "Completed:";
			this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(8, 112);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(130, 23);
			this.label4.TabIndex = 29;
			this.label4.Text = "Total Presentations:";
			this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(8, 64);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(130, 23);
			this.label3.TabIndex = 28;
			this.label3.Text = "Current Level:";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(8, 40);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(130, 23);
			this.label2.TabIndex = 27;
			this.label2.Text = "Current Secondary Stim:";
			this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(8, 16);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(130, 23);
			this.label1.TabIndex = 26;
			this.label1.Text = "Current Primary Stim:";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// btnPause
			// 
			this.btnPause.Location = new System.Drawing.Point(16, 288);
			this.btnPause.Name = "btnPause";
			this.btnPause.Size = new System.Drawing.Size(72, 24);
			this.btnPause.TabIndex = 45;
			this.btnPause.Text = "Pause";
			this.btnPause.Click += new System.EventHandler(this.btnPause_Click);
			// 
			// btnReset
			// 
			this.btnReset.Location = new System.Drawing.Point(16, 328);
			this.btnReset.Name = "btnReset";
			this.btnReset.Size = new System.Drawing.Size(72, 24);
			this.btnReset.TabIndex = 46;
			this.btnReset.Text = "Reset";
			this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
			// 
			// label6
			// 
			this.label6.Location = new System.Drawing.Point(216, 136);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(64, 24);
			this.label6.TabIndex = 47;
			this.label6.Text = "Remaining:";
			this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// txtRemaining
			// 
			this.txtRemaining.Location = new System.Drawing.Point(288, 136);
			this.txtRemaining.Name = "txtRemaining";
			this.txtRemaining.ReadOnly = true;
			this.txtRemaining.Size = new System.Drawing.Size(56, 20);
			this.txtRemaining.TabIndex = 48;
			this.txtRemaining.Text = "";
			// 
			// timerPlay
			// 
			this.timerPlay.Tick += new System.EventHandler(this.timerPlay_Tick);
			// 
			// button2
			// 
			this.button2.Location = new System.Drawing.Point(200, 272);
			this.button2.Name = "button2";
			this.button2.Size = new System.Drawing.Size(80, 48);
			this.button2.TabIndex = 49;
			this.button2.Text = "button2";
			this.button2.Visible = false;
			this.button2.Click += new System.EventHandler(this.button2_Click);
			// 
			// timerPulse
			// 
			this.timerPulse.Interval = 1000;
			this.timerPulse.Tick += new System.EventHandler(this.timerPulse_Tick);
			// 
			// btnGenReport
			// 
			this.btnGenReport.Location = new System.Drawing.Point(16, 360);
			this.btnGenReport.Name = "btnGenReport";
			this.btnGenReport.Size = new System.Drawing.Size(72, 24);
			this.btnGenReport.TabIndex = 50;
			this.btnGenReport.Text = " Report";
			this.btnGenReport.Click += new System.EventHandler(this.btnGenReport_Click);
			// 
			// label7
			// 
			this.label7.Location = new System.Drawing.Point(0, 160);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(144, 24);
			this.label7.TabIndex = 51;
			this.label7.Text = "Catch Trials:";
			this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// txtCatchTrials
			// 
			this.txtCatchTrials.Location = new System.Drawing.Point(152, 160);
			this.txtCatchTrials.Name = "txtCatchTrials";
			this.txtCatchTrials.Size = new System.Drawing.Size(80, 20);
			this.txtCatchTrials.TabIndex = 52;
			this.txtCatchTrials.Text = "";
			// 
			// btnEditCatch
			// 
			this.btnEditCatch.Location = new System.Drawing.Point(240, 160);
			this.btnEditCatch.Name = "btnEditCatch";
			this.btnEditCatch.Size = new System.Drawing.Size(48, 18);
			this.btnEditCatch.TabIndex = 53;
			this.btnEditCatch.Text = "Edit";
			this.btnEditCatch.Click += new System.EventHandler(this.btnEditCatch_Click);
			// 
			// txtCatchPC
			// 
			this.txtCatchPC.Location = new System.Drawing.Point(200, 160);
			this.txtCatchPC.Name = "txtCatchPC";
			this.txtCatchPC.ReadOnly = true;
			this.txtCatchPC.Size = new System.Drawing.Size(32, 20);
			this.txtCatchPC.TabIndex = 54;
			this.txtCatchPC.Text = "";
			// 
			// PairedComparison
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(840, 502);
			this.Controls.Add(this.txtCatchPC);
			this.Controls.Add(this.txtCatchTrials);
			this.Controls.Add(this.txtRemaining);
			this.Controls.Add(this.txtStdErr);
			this.Controls.Add(this.txtTime);
			this.Controls.Add(this.txtSecondary);
			this.Controls.Add(this.txtLevel);
			this.Controls.Add(this.txtTotalPresentation);
			this.Controls.Add(this.txtCompleted);
			this.Controls.Add(this.txtPrimary);
			this.Controls.Add(this.btnEditCatch);
			this.Controls.Add(this.label7);
			this.Controls.Add(this.btnGenReport);
			this.Controls.Add(this.button2);
			this.Controls.Add(this.label6);
			this.Controls.Add(this.btnReset);
			this.Controls.Add(this.btnPause);
			this.Controls.Add(this.label9);
			this.Controls.Add(this.listView2);
			this.Controls.Add(this.listView1);
			this.Controls.Add(this.label8);
			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.Controls.Add(this.btnPlay);
			this.Controls.Add(this.sbStatus);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Name = "PairedComparison";
			this.Text = "PairedComparison";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.PairedComparison_Closing);
			((System.ComponentModel.ISupportInitialize)(this.sbpFolder)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion
		
#region Our Methods
		public bool Init()
		{
			R = new Random(DateTime.Now.Millisecond);
			m_strFolderPath = ((Stim)mainmenu.def.PairedStims[0]).strStimDirectory;
			player.Init();
			CreateFileLists(m_strFolderPath,1);//second parameter is dummy. put to make method signature different
			InitView();
			InitStims();
			WriteStart();
			pcGame = new StarGame.GameForm(mainmenu.def.bSingleScreen,mainmenu.def.FeedbackLoc,mainmenu.def.FeedbackSize);
			pcGame.Text= "Paired Comparison";
			pcGame.ParentGame ="PAIRED_COMPARISON";
			pcGame.ShowPoints = false;
			pcGame.Show();
			pcGame.ButtonEvt+=new StarGame.GameForm.ButtonEventHandler(pcGame_ButtonEvt);
			pcGame.KeyEvt += new StarGame.GameForm.KeyEventHandler(pcGame_KeyEvt);
			pcGame.SetupGame(mainmenu.def.strFeedbackDir,(string) mainmenu.def.Feedback[0]);
			pcGame.DrawButtons(mainmenu.def.Buttons);
			
			PLAY_INTERVAL = mainmenu.def.nIntervalLen; // Interval Length from def file;time between one pair to next
			INTER_STIM_INTERVAL = mainmenu.def.nIntervalSpace;//Interval Space from def file;time between files in same pair
			timerPlay.Interval = PLAY_INTERVAL;
			bEnableCatchTrial = mainmenu.def.bCatchTrial;
			timerPulse.Start();//pulse, every 100ms
			CombinStims = Factorial((double)StimCategoryCount)/(Factorial((double)(StimCategoryCount-StimCount))*2);
			//Calculate numbers for catch trials
			if(bEnableCatchTrial)
			{   //total non catch trials = num of files* Combination(TotalCategory,2)*repetitions
				double dTotNonCatch = StimCount * CombinStims*mainmenu.def.nReps;
				//mainmenu.def.nCatchFreq (A) = %of catch trials on whole trials
				// so, #catch trial = A*n/(100-A); A% = #catch trial/(#catch trial + #non catch trial)
				iTotCatchNum = (int)(mainmenu.def.nCatchFreq*dTotNonCatch)/(100-mainmenu.def.nCatchFreq);
				//#catch trials cannot exceed num of non catch trials.
				if(iTotCatchNum > dTotNonCatch) iTotCatchNum=(int)dTotNonCatch;
				//
				iCatchTrialInterval = (int)Math.Round((double)(dTotNonCatch+iTotCatchNum)/(double)iTotCatchNum,0);

				txtCatchPC.Text = mainmenu.def.nCatchFreq.ToString()+ " %";
			}
			if(iCatchTrialInterval == 0) iCatchTrialInterval = 1000; // to prevent division by zero
			this.txtTotalPresentation.Text = (StimCount*CombinStims*mainmenu.def.nReps + iTotCatchNum).ToString();
			pcGame.SetTotalGames(int.Parse(this.txtTotalPresentation.Text));
			this.txtCatchTrials.Text = iTotCatchNum.ToString();
			this.txtCatchTrials.ReadOnly = true;
			this.btnEditCatch.Text="Edit";
			return true;
		}

		private bool InitStims()
		{
			Stim s;
			Stim tempStim;
			StimEBW.Stims.Clear();
			StimRBW.Stims.Clear();
			StimFC.Stims.Clear();
		//	if(lstEBW.Count != lstRBW.Count && lstRBW.Count != lstFC.Count) return false;
			if(lstEBW.Count >0)StimCount = lstEBW.Count;
			else if(lstRBW.Count > 0)StimCount = lstRBW.Count;
			else if(lstFC.Count > 0) StimCount = lstFC.Count;

			for(int i=0;i<StimCount;i++)
			{   
				s = (Stim)mainmenu.def.PairedStims[0];
				s.buffer.ToBePlayed=true;
				s.buffer.AmplificationType = s.AmpType;
			    
				StimCategoryCount = 0;
				if(lstEBW.Count > 0 )
				{  
					StimCategoryCount++;;
					tempStim = s.Copy();
					tempStim.strFile = lstEBW[i]+"-EBW.wav";
					tempStim.strInfo="EBW";
					if(mainmenu.def.bPlayLRStereo)
					{
						string strL = s.strStimDirectory+"\\"+lstEBW[i]+"-EBW-L.wav";
						string strR = s.strStimDirectory+"\\"+lstEBW[i]+"-EBW-R.wav";
						tempStim.buffer.SetMS(GetLRMemoryStream(strL,strR,tempStim.AmpType),"Both");
					}
					else 
					{
						FileInfo f = new FileInfo(s.strStimDirectory+"\\"+tempStim.strFile);
						tempStim.buffer.WaveFile(f,mainmenu.MaxAmplitude,tempStim.strEar,tempStim.bLoop,tempStim.AmpType);
					}
					tempStim.buffer.ToBePlayed = true;
					tempStim.buffer.AmplificationType = s.AmpType;
					StimEBW.Stims.Add(tempStim); // EBW done
				}
				if(lstRBW.Count > 0)
				{	
					StimCategoryCount++;
					tempStim = s.Copy();
					tempStim.strFile = lstRBW[i]+"-RBW.wav";
					tempStim.strInfo ="RBW";
					if(mainmenu.def.bPlayLRStereo)
					{
						string strL = s.strStimDirectory+"\\"+lstRBW[i]+"-RBW-L.wav";
						string strR = s.strStimDirectory+"\\"+lstRBW[i]+"-RBW-R.wav";
						tempStim.buffer.SetMS(GetLRMemoryStream(strL,strR,tempStim.AmpType),"Both");
					}
					else 
					{

						FileInfo f = new FileInfo(s.strStimDirectory+"\\"+tempStim.strFile);
						tempStim.buffer.WaveFile(f,mainmenu.MaxAmplitude,tempStim.strEar,tempStim.bLoop,tempStim.AmpType);
					}
					tempStim.buffer.ToBePlayed = true;
					tempStim.buffer.AmplificationType = s.AmpType;
					StimRBW.Stims.Add(tempStim); // RBW done
				}
				if(lstFC.Count > 0 )
				{	
					StimCategoryCount++;
					tempStim = s.Copy();
					tempStim.strFile = lstFC[i]+"-NFC.wav";
					tempStim.strInfo="NFC";
					if(mainmenu.def.bPlayLRStereo)
					{
						string strL = s.strStimDirectory+"\\"+lstFC[i]+"-NFC-L.wav";
						string strR = s.strStimDirectory+"\\"+lstFC[i]+"-NFC-R.wav";
						tempStim.buffer.SetMS(GetLRMemoryStream(strL,strR,tempStim.AmpType),"Both");
					}
					else
					{
						FileInfo f = new FileInfo(s.strStimDirectory+"\\"+tempStim.strFile);
						tempStim.buffer.WaveFile(f,mainmenu.MaxAmplitude,tempStim.strEar,tempStim.bLoop,tempStim.AmpType);
					}
					tempStim.buffer.ToBePlayed = true;
					tempStim.buffer.AmplificationType = s.AmpType;
					StimFC.Stims.Add(tempStim); // FC done  
				}
				//same object added to three different lists. correct this.
			}
			StimEBW.nTotalStims = lstEBW.Count;
			StimRBW.nTotalStims = lstRBW.Count;
			StimFC.nTotalStims  = lstFC.Count;
			return true;
		}
		/// <summary>
		/// Combines two files as one stereo file
		/// </summary>
		/// <param name="fnameL">This file gets set to left channel of output stereo</param>
		/// <param name="fnameR">This file gets set to right channel of output stereo</param>
		/// <returns>Stereo memory stream</returns>
		private MemoryStream GetLRMemoryStream(string fnameL,string fnameR,WaveLib.AmplificationTypes AmpType)
		{
			MemoryStream ms=new MemoryStream();
			WaveLib.WaveFile wf = new WaveLib.WaveFile(new FileInfo(fnameL),3 ,AmpType);
			wf.Open();
			ms.Write(wf.ms.ToArray(),0,(int)wf.ms.Length );
			wf.Close();
			wf = new WaveLib.WaveFile(new FileInfo(fnameR),3,AmpType);
			wf.Open();
			ms.Write(wf.ms.ToArray(),0,(int)wf.ms.Length );
			ms = AdjustToLR(ms);
			wf.Close();
			return ms;
		}
		private MemoryStream AdjustToLR(MemoryStream tms)
		{
			MemoryStream mixed = new MemoryStream();
			long len = tms.Length/2;
			byte []byteArr = tms.ToArray();
			for(int i=0;i<len;i+=8)
			{
				mixed.Write(byteArr,i,4);
				mixed.Write(byteArr,i+(int)len,4);
			}
			return mixed;
		}
		private void InitView()
		{
			try
			{
				ColumnHeader c  = new ColumnHeader();
				c.Text = "Primary Stim";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Pri.Level";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Secondary Stim";
				c.Width = -2;
				listView1.Columns.Add(c);
				c  = new ColumnHeader();
				c.Text = "Sec. Level";
				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 = "Stim Cat";
				c.Width = -2;
				listView1.Columns.Add(c);
				
				c  = new ColumnHeader();
				c.Text = "Ear";
				c.Width = -2;
				listView1.Columns.Add(c);
				 
				c  = new ColumnHeader();
				c.Text = "Pressed Button";
				c.Width = -2;
				listView1.Columns.Add(c);
				listView1.Update();

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

				string strTemp=string.Empty;
				c = new ColumnHeader();
				c.Text = "Combination";
				listView2.Columns.Add(c);
				
				c = new ColumnHeader();
				c.Text = "#Runs";
				listView2.Columns.Add(c);
					
				c = new ColumnHeader();
				c.Text = "# EBW       ";
				listView2.Columns.Add(c);

				c = new ColumnHeader();
				c.Text = "# RBW      ";
				listView2.Columns.Add(c);

				c = new ColumnHeader();
				c.Text = "# FC      ";
				listView2.Columns.Add(c);

				c = new ColumnHeader();
				c.Text = "# No Diff";
				listView2.Columns.Add(c);
		
				c = new ColumnHeader();
				c.Text = "# Repeat";
				listView2.Columns.Add(c);

				foreach(ColumnHeader ch in listView2.Columns)
					ch.Width=-2;
			InitList2();
			}
			catch(Exception err)
			{
				MessageBox.Show("Error configuring result data structures: " + err.Message);
			}
		}
		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 bool CreateFileLists(string strFolder,int a)
		{
			char [] delim = new char [] {'-','.'};
			try 
			{
				string tempStr;
				DirectoryInfo dir = new DirectoryInfo(strFolder);
				FileInfo [] fileList = dir.GetFiles();
				// clear lists just in case
				lstEBW.Clear();
				lstRBW.Clear();
				lstFC.Clear();

				foreach(FileInfo fi in fileList)
				{
					tempStr = fi.Name;
					// Filenames should occur as : filename-EBW.extension
					string []sTempSplit = tempStr.Split(delim);
					switch (sTempSplit[1])
					{
						case "EBW":
						case "ebw":lstEBW.Add(sTempSplit[0].Trim());
							break;
						case "RBW":
						case "rbw": lstRBW.Add(sTempSplit[0].Trim());
							break;
						case "NFC":
						case "nfc": lstFC.Add(sTempSplit[0].Trim());
							break;
					}
				}
				lstEBW.Sort();
				lstRBW.Sort();
				lstFC.Sort();
				//Check if the files are named properly
				/*
				for(int i=0;i<lstEBW.Count;i++)
				{
					string tStr = (string) lstEBW[i];
					if(lstRBW.IndexOf(tStr)!= i || lstFC.IndexOf(tStr)!=i)
					{
						MessageBox.Show("Error in files "+ tStr);
						return false;
					}
				}
				*/
			}
			catch(Exception e)
			{
				MessageBox.Show(e.Message);
				return false;
			}
			return true;
		}
		private double Factorial(double num)
		{
			if (num <= 1) return 1;
			return Factorial(num-1)*num;
		}
/// <summary>
/// Given a folder name, seperates files in this folder in 3 lists
/// for EBW, RBW and FC
/// </summary>
/// <param name="strFolder"></param>
/// <returns></returns>

	private bool CreateFileLists(string strFolder)
	{
		char [] delim = new char [] {'-','.'};
		try 
		{
			string tempStr;
			DirectoryInfo dir = new DirectoryInfo(strFolder);
			FileInfo [] fileList = dir.GetFiles();
			// clear lists just in case
			lstEBW.Clear();
			lstRBW.Clear();
			lstFC.Clear();

			foreach(FileInfo fi in fileList)
			{
				tempStr = fi.Name;
				// Filenames should occur as : filename-EBW.extension
				string []sTempSplit = tempStr.Split(delim);
				switch (sTempSplit[1])
				{
					case "EBW":
					case "ebw":lstEBW.Add(sTempSplit[0].Trim());
								break;
					case "RBW":
					case "rbw": lstRBW.Add(sTempSplit[0].Trim());
								break;
					case "NFC":
					case "nfc": lstFC.Add(sTempSplit[0].Trim());
								break;
				}
			}
			lstEBW.Sort();
			lstRBW.Sort();
			lstFC.Sort();
			//Check if the files are named properly
			for(int i=0;i<lstEBW.Count;i++)
			{
				string tStr = (string) lstEBW[i];
				if(lstRBW.IndexOf(tStr)!= i || lstFC.IndexOf(tStr)!=i)
				{
					MessageBox.Show("Error in files "+ tStr);
					return false;
				}
			}
		}
		catch(Exception e)
		{
			MessageBox.Show(e.Message);
			return false;
		}
		return true;
	}

		private void PlayAtRandom()
		{
			for(int i =0; i<=2;i++)
			{
				StimEBW.CurrentStim = (Stim)StimEBW.Stims[i];
				StimRBW.CurrentStim = (Stim)StimRBW.Stims[i];
				StimFC.CurrentStim  = (Stim)StimFC.Stims[i];
				player.Signals[0]=StimEBW.CurrentStim.buffer;
				player.Signals[1]=StimRBW.CurrentStim.buffer;
				player.Signals[2]=StimFC.CurrentStim.buffer;
				player.PlayMemoryStream(player.Signals[0].ms);
				player.PlayMemoryStream(player.Signals[1].ms);
				player.PlayMemoryStream(player.Signals[2].ms);
			}
		}

		private bool VerifyNoDuplicate(int row,int[]cols)
		{//
			string testStr1 = row.ToString()+cols[0].ToString()+cols[1].ToString();
			string testStr2 = row.ToString()+cols[1].ToString()+cols[0].ToString();
			int iRun=0;
			if(DC.ContainsKey(testStr1)) iRun = (int)DC[testStr1];
			if(DC.ContainsKey(testStr2))iRun += (int)DC[testStr2];
			return iRun>=mainmenu.def.nReps;
			//return DoneCombination.Contains(testStr1)|| DoneCombination.Contains(testStr2);
		}
		private void PlayInRandomPair() 
		{
			int iRowToPlay ;
			int []iColsToPlay; // chooses between EBW,RBW or FC
			int iLoopCount=0;
			int CATCH_START_AT = 1; // catch run starts at this run
			//this run is catch trial if CatchTrial is enabled, and playcount is certain multiple of catch frequency
			bIsCatchTrial  = mainmenu.def.bCatchTrial && iPlayCount % iCatchTrialInterval ==CATCH_START_AT;
			if(1+(iPlayCount-CATCH_START_AT)/iCatchTrialInterval > iTotCatchNum)bIsCatchTrial=false;
			do
			{   iLoopCount++;
				iRowToPlay=GetRandomRow();
				iColsToPlay = GetRandomPair();
				if(iLoopCount>10000) break;//avoid infinite loops
			}while(VerifyNoDuplicate(iRowToPlay,iColsToPlay));

			ArrayList StimCollection = new ArrayList ();

			if(StimEBW.nTotalStims > 0)	StimCollection.Add(StimEBW);
			if(StimRBW.nTotalStims > 0) StimCollection.Add(StimRBW);
			if(StimFC.nTotalStims > 0 ) StimCollection.Add(StimFC);
			
			Primary = (Run) StimCollection[iColsToPlay[0]]; //choose which to play as primary
			Primary.CurrentStim = (Stim)Primary.Stims[iRowToPlay];
            Secondary = (Run)StimCollection[iColsToPlay[1]]; // choose which to play as secondary
			Secondary.CurrentStim = (Stim)Secondary.Stims[iRowToPlay];
			
			Primary.nCurrentLevel= (int)Primary.CurrentStim.nOrigin;
			Secondary.nCurrentLevel=(int)Primary.CurrentStim.nOrigin;

			string strPriStim = Primary.CurrentStim.strFile;
			string strSecStim = Secondary.CurrentStim.strFile;
			this.txtPrimary.Text= strPriStim;
			this.txtSecondary.Text=strSecStim;
			this.txtLevel.Text = Primary.nCurrentLevel.ToString();

			Primary.CurrentStim.buffer.SetLevel((int)GetLevel(Primary));
			Secondary.CurrentStim.buffer.SetLevel((int)GetLevel(Secondary));

			PlayStreams(Primary.CurrentStim.buffer,Secondary.CurrentStim.buffer);
			
			//add this combination to done list
			if(iColsToPlay[1] > iColsToPlay[0])
				AddKeyValue(iRowToPlay.ToString()+iColsToPlay[0].ToString()+iColsToPlay[1].ToString());
			else
				AddKeyValue(iRowToPlay.ToString()+iColsToPlay[1].ToString()+iColsToPlay[0].ToString());
			pcGame.SetProgressBar(iPlayCount+1);
			
		}
		public void AddKeyValue(string sValue)
		{
			if(DC.ContainsKey(sValue))
			{
				int i =(int) DC[sValue];
				i++;
				DC.Remove(sValue);
				DC.Add(sValue,i);
			}
			else
				DC.Add(sValue,1);
				
			//DoneCombination.Add(sValue);
		}
		private int GetRandomRow()
		{// Selects which of the many stims is to be played this time
			int n = StimCount;
			return R.Next(0,n);
		}
		private int []GetRandomPair()
		{
			int n = StimCategoryCount ;
			int [] iArray = new int[2];
			
			iArray[0]=R.Next(0,n); // get val btn 0 and n
			iArray[1]=R.Next(0,n);
			if(bIsCatchTrial)
				{  //get value between 0 to n
					iArray[1]=(iPlayCount/iCatchTrialInterval)% n; 
					iArray[0]=iArray[1];
				 }
			else
			{//make sure they dont return the same number
				while(iArray[0]==iArray[1])iArray[1]=R.Next(0,n);
			}
			return iArray;
		}
		
		private void WriteStart()
		{
			string strTemp = outfile.FullName;
			if(strTemp.IndexOf(".txt")>0)
				strTemp = strTemp.Replace(".txt",".dat");
			else
				strTemp += ".dat";
			output = new StreamWriter(strTemp,false);
			output.WriteLine("%PAIRED COMPARISON 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);
			
			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(string.Empty);

			output.WriteLine("Primary      Pri-Level   Secondary  Sec-Level Response Stim-Cat Ear   Button");
			output.Flush();
			output.Close();
		}
		private void WriteResult()
		{	
			UpdateList1();
			UpdateList2();
			UpdateStats();
			WriteEachStimToFile();
			//Fill Text boxes
			if(!Primary.strAction.Equals("Repeat"))
					iPlayCount++;
			this.txtCompleted.Text =  iPlayCount.ToString();
			this.txtRemaining.Text = (int.Parse(txtTotalPresentation.Text)-iPlayCount).ToString();
			TimeSpan s = DateTime.Now-dtStart;
			this.txtTime.Text= string.Format("{0}:{1}:{2}",s.Hours,s.Minutes,s.Seconds);
		}

		private void ClearTextboxes()
		{
			foreach(Control c in this.Controls)
			{	
				if(c.GetType().Equals(typeof(TextBox)))
				{
					c.Text="";
				}

			}
		this.txtTotalPresentation.Text = (StimCount*CombinStims*mainmenu.def.nReps + iTotCatchNum).ToString();
			this.txtCatchTrials.Text = iTotCatchNum.ToString();
			txtCatchPC.Text = mainmenu.def.nCatchFreq.ToString()+ " %";
		}
		private void UpdateList1()
		{
			//output = new StreamWriter(outfile.ToString(),true);
			string strPriStim;
			strPriStim = Primary.CurrentStim.strFile;
			string  strPriEar;
			strPriEar = Primary.CurrentStim.strEar;

			string strSecStim;
			if(Secondary.CurrentStim==null)
				strSecStim = "NONE";
			else if(Secondary.CurrentStim.strFile.Length>0)
				strSecStim = Secondary.CurrentStim.strFile;
			else
				strSecStim = Secondary.CurrentStim.strType+ " " +Secondary.CurrentStim.nFreq.ToString();

			string strPriCurrentLevel = Primary.nCurrentLevel.ToString();
			if(Primary.CurrentStim.AmpType==WaveLib.AmplificationTypes.None)
				strPriCurrentLevel = "None";

			listView1.BeginUpdate();

			ListViewItem i = new ListViewItem();
			i.Text = strPriStim;
			i.SubItems.Add(strPriCurrentLevel);
			i.SubItems.Add(strSecStim);
			i.SubItems.Add(Secondary.nCurrentLevel.ToString());
			//response
			i.SubItems.Add(Primary.CurrentResponse);
			//category
			i.SubItems.Add(Primary.CurrentStim.strDesiredResponse);
			//ear
			i.SubItems.Add(strPriEar);
			//clicked button
			i.SubItems.Add(pcGame.strButtonClicked.ToLower());
			listView1.Items.Add(i);
			i.Selected=true;
			if(iPlayCount % 2 == 0)i.BackColor=Color.White;
			else i.BackColor=Color.LightGray;

			listView1.EnsureVisible(i.Index);
			listView1.EndUpdate();
		}
		private void InitList2()
		{
			listView2.BeginUpdate();
			ListViewItem i = new ListViewItem();
			i.Text = "EBW-RBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "RBW-EBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);
			
			i = new ListViewItem();
			i.Text = "TOT-ER";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);

			i= new ListViewItem();
			i.Text = "EBW-NFC";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			listView2.Items.Add(i);

			i=new ListViewItem();
			i.Text = "NFC-EBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			listView2.Items.Add(i);

			i=new ListViewItem();
			i.Text = "TOT-EF";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			listView2.Items.Add(i);

			i=new ListViewItem();
			i.Text = "RBW-NFC";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "NFC-RBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "TOT-RF";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor=Color.Gray;
			listView2.Items.Add(i);
			
			i= new ListViewItem();
			i.Text=" ";
			i.SubItems.Add("#Played");
			for(int j=0;j<mainmenu.def.Buttons.Count;j++)
			{  Button b = (Button)mainmenu.def.Buttons[j];
				if(!b.Text.ToLower().Equals("repeat"))i.SubItems.Add("#"+b.Text);
			}
			i.SubItems.Add("#Repeat");//add repeat at last

			i.BackColor= Color.Yellow;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "EBW-EBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor = Color.Yellow;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "RBW-RBW";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor = Color.Yellow;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "NFC-NFC";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor = Color.Yellow;
			listView2.Items.Add(i);

			i = new ListViewItem();
			i.Text = "TOT-CT";
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.SubItems.Add("0");
			i.BackColor = Color.Yellow;
			listView2.Items.Add(i);

			listView2.EndUpdate();
			
		}
		private void UpdateList2()
		{
			string strPri = Primary.CurrentStim.strInfo;
			string strSec = Secondary.CurrentStim.strInfo;
			ListViewItem li = new ListViewItem();
			//File pair eg. EBW-FC
			string s = strPri+"-"+strSec;
			//Find index corresponding to File pair eg EBW-FC
			for(int kk =0;kk<listView2.Items.Count;kk++)
			{
				if(s.Equals(listView2.Items[kk].SubItems[0].Text))
				{
					li=listView2.Items[kk];
					break;
				}
			}
			
			if(li.SubItems[1].Text.Equals(string.Empty)) return;
			
			//Count number of pairs
			int iCountNum = int.Parse(li.SubItems[1].Text);
			if(!Primary.strAction.Equals("Repeat"))
			{//Dont count if this is a repeat round
				iCountNum++;
				li.SubItems[1].Text=iCountNum.ToString();
			}
			if(bIsCatchTrial)
			{// Combination(0) - Num count(1) - EBW(2) - RBW(3) - FC(4) - NIL(5)-Repeat(6)
				switch(Primary.strAction)//which button was pressed 1=A, 2=B, 3=NIL
				{
					case "1":
						iCountNum = int.Parse(li.SubItems[2].Text);
						iCountNum ++;
						li.SubItems[2].Text=iCountNum.ToString();
						break;
					case "2":iCountNum = int.Parse(li.SubItems[3].Text);
						iCountNum ++;
						li.SubItems[3].Text=iCountNum.ToString();
						break;
					case "3":iCountNum = int.Parse(li.SubItems[4].Text);
						iCountNum ++;
						li.SubItems[4].Text=iCountNum.ToString();
						break;
					case "Repeat":iCountNum = int.Parse(li.SubItems[5].Text);
						iCountNum++;
						li.SubItems[5].Text=iCountNum.ToString();
						break;
				}
			}
			else //if this is not a catch trial run
			switch(Primary.CurrentResponse)
			{// Combination(0) - Num count(1) - EBW(2) - RBW(3) - FC(4) - NIL(5)
				case "EBW": //index 2
					iCountNum = int.Parse(li.SubItems[2].Text);
					iCountNum ++;
					li.SubItems[2].Text=iCountNum.ToString();
					break;
				case "RBW": // index 3
					iCountNum = int.Parse(li.SubItems[3].Text);
					iCountNum ++;
					li.SubItems[3].Text=iCountNum.ToString();
					break;
				case "NFC":
					iCountNum = int.Parse(li.SubItems[4].Text);
					iCountNum ++;
					li.SubItems[4].Text=iCountNum.ToString();
					break;
				case "NIL":
					iCountNum = int.Parse(li.SubItems[5].Text);
					iCountNum++;
					li.SubItems[5].Text= iCountNum.ToString();
					break;
				case "Repeat":
					iCountNum = int.Parse(li.SubItems[6].Text);
					iCountNum++;
					li.SubItems[6].Text=iCountNum.ToString();
					break;
			}
			
		}

		private void PlayStreams(WaveLib.WaveBuffer ms1,WaveLib.WaveBuffer ms2)
		{	
			bPlayInProgress=true;
			LastPlayMoment = DateTime.Now;
			System.Threading.Thread.Sleep(PLAY_INTERVAL/2);	
			pcGame.game.BlankScreen(true);
			System.Threading.Thread.Sleep(PLAY_INTERVAL/2);	
			pcGame.SetButtonShade("1",true);//make button 1 to glow
			player.PlayMemoryStream(ms1.ms);
			pcGame.SetButtonShade("1",false);
			Application.DoEvents();
			System.Threading.Thread.Sleep(INTER_STIM_INTERVAL);		
			pcGame.SetButtonShade("2",true);
			player.PlayMemoryStream(ms2.ms);
			pcGame.SetButtonShade("2",false);
			bPlayInProgress=false;
		}
		private void UpdateStats()
		{
			int TotER=0,TotEF=0,TotRF=0,TotCatch;//totals of each pair, order irrelevant
			int ERIndex=0,REIndex=1,EFIndex=2,FEIndex=3,RFIndex=4,FRIndex=5;
			int EEIndex=6,RRIndex=7,FFIndex=8;
			int TotERIndex=9,TotEFIndex=10,TotRFIndex=11,TotCTIndex=12;
			double pE,pR,pF,pN,pRe; //percentage of time p,e,f, Nil,repeat selected;
			
			foreach(ListViewItem li in listView2.Items)
			{
				switch(li.SubItems[0].Text)
				{
					case "EBW-RBW":ERIndex = li.Index;break;
					case "RBW-EBW":REIndex = li.Index;break;
					case "EBW-NFC": EFIndex = li.Index;break;
					case "NFC-EBW":FEIndex = li.Index;break;
					case "RBW-NFC": RFIndex = li.Index;break;
					case "NFC-RBW": FRIndex = li.Index;break;
					case "EBW-EBW":EEIndex = li.Index;break;
					case "RBW-RBW":RRIndex = li.Index;break;
					case "NFC-NFC":FFIndex = li.Index;break;
					case"TOT-ER": TotERIndex=li.Index;break;
					case"TOT-EF": TotEFIndex=li.Index;break;
					case "TOT-RF": TotRFIndex=li.Index;break;
					case"TOT-CT": TotCTIndex = li.Index;break;
				}
			}
			//Calculate Totals of each pair,order irrelevant
			TotER = int.Parse(listView2.Items[ERIndex].SubItems[1].Text) + int.Parse(listView2.Items[REIndex].SubItems[1].Text);
			TotEF = int.Parse(listView2.Items[EFIndex].SubItems[1].Text) + int.Parse(listView2.Items[FEIndex].SubItems[1].Text);
			TotRF = int.Parse(listView2.Items[RFIndex].SubItems[1].Text) + int.Parse(listView2.Items[FRIndex].SubItems[1].Text);
			TotCatch=int.Parse(listView2.Items[EEIndex].SubItems[1].Text) + int.Parse(listView2.Items[RRIndex].SubItems[1].Text)+ int.Parse(listView2.Items[FFIndex].SubItems[1].Text);
			//avoid division by zero;
			if(TotER==0)TotER=1;
			if(TotEF==0)TotEF=1;
			if(TotRF==0)TotRF=1;
			if(TotCatch==0)TotCatch=1;
			//Calculate %of selection in each pair
			//ER pair
			pE = (int.Parse(listView2.Items[ERIndex].SubItems[2].Text) + int.Parse(listView2.Items[REIndex].SubItems[2].Text))*100/TotER;
			pR = (int.Parse(listView2.Items[ERIndex].SubItems[3].Text) + int.Parse(listView2.Items[REIndex].SubItems[3].Text))*100/TotER;
			pN = (int.Parse(listView2.Items[ERIndex].SubItems[5].Text) + int.Parse(listView2.Items[REIndex].SubItems[5].Text))*100/TotER;
			pRe= (int.Parse(listView2.Items[ERIndex].SubItems[6].Text) + int.Parse(listView2.Items[REIndex].SubItems[6].Text))*100/TotER;

			listView2.Items[TotERIndex].SubItems[1].Text = TotER.ToString();
			listView2.Items[TotERIndex].SubItems[2].Text  = pE.ToString()+" %";
			listView2.Items[TotERIndex].SubItems[3].Text = pR.ToString()+ " %";
			listView2.Items[TotERIndex].SubItems[5].Text = pN.ToString()+" %";
			listView2.Items[TotERIndex].SubItems[6].Text = pRe.ToString()+" %";
			
			//EF pair
			pE = (int.Parse(listView2.Items[EFIndex].SubItems[2].Text) + int.Parse(listView2.Items[FEIndex].SubItems[2].Text))*100/TotEF;
			pF = (int.Parse(listView2.Items[EFIndex].SubItems[4].Text) + int.Parse(listView2.Items[FEIndex].SubItems[4].Text))*100/TotEF;
			pN = (int.Parse(listView2.Items[EFIndex].SubItems[5].Text) + int.Parse(listView2.Items[FEIndex].SubItems[5].Text))*100/TotEF;
			pRe= (int.Parse(listView2.Items[EFIndex].SubItems[6].Text) + int.Parse(listView2.Items[FEIndex].SubItems[6].Text))*100/TotEF;

			listView2.Items[TotEFIndex].SubItems[1].Text = TotEF.ToString();
			listView2.Items[TotEFIndex].SubItems[2].Text  = pE.ToString()+" %";
			listView2.Items[TotEFIndex].SubItems[4].Text = pF.ToString()+ " %";
			listView2.Items[TotEFIndex].SubItems[5].Text = pN.ToString()+" %";
			listView2.Items[TotEFIndex].SubItems[6].Text = pRe.ToString()+" %";

			
			//RF pair
			pR = (int.Parse(listView2.Items[RFIndex].SubItems[3].Text) + int.Parse(listView2.Items[FRIndex].SubItems[3].Text))*100/TotRF;
			pF = (int.Parse(listView2.Items[RFIndex].SubItems[4].Text) + int.Parse(listView2.Items[FRIndex].SubItems[4].Text))*100/TotRF;
			pN = (int.Parse(listView2.Items[RFIndex].SubItems[5].Text) + int.Parse(listView2.Items[FRIndex].SubItems[5].Text))*100/TotRF;
			pRe= (int.Parse(listView2.Items[RFIndex].SubItems[6].Text) + int.Parse(listView2.Items[FRIndex].SubItems[6].Text))*100/TotRF;

			listView2.Items[TotRFIndex].SubItems[1].Text = TotRF.ToString();
			listView2.Items[TotRFIndex].SubItems[3].Text  = pR.ToString()+" %";
			listView2.Items[TotRFIndex].SubItems[4].Text = pF.ToString()+ " %";
			listView2.Items[TotRFIndex].SubItems[5].Text = pN.ToString()+" %";
			listView2.Items[TotRFIndex].SubItems[6].Text = pRe.ToString()+" %";

			//Catch Trials0
/*button 1 */pE = (int.Parse(listView2.Items[EEIndex].SubItems[2].Text)+int.Parse(listView2.Items[RRIndex].SubItems[2].Text)+int.Parse(listView2.Items[FFIndex].SubItems[2].Text))*100/TotCatch;
/*button 2 */pR = (int.Parse(listView2.Items[EEIndex].SubItems[3].Text)+int.Parse(listView2.Items[RRIndex].SubItems[3].Text)+int.Parse(listView2.Items[FFIndex].SubItems[3].Text))*100/TotCatch;
			//pF = (int.Parse(listView2.Items[FFIndex].SubItems[4].Text))*100/TotCatch;
/*no diff */pN = (int.Parse(listView2.Items[EEIndex].SubItems[4].Text) + int.Parse(listView2.Items[RRIndex].SubItems[4].Text)+ int.Parse(listView2.Items[FFIndex].SubItems[4].Text))*100/TotCatch;
/*no Repeat*/pRe= (int.Parse(listView2.Items[EEIndex].SubItems[5].Text) + int.Parse(listView2.Items[RRIndex].SubItems[5].Text)+ int.Parse(listView2.Items[FFIndex].SubItems[5].Text))*100/TotCatch;
	
			listView2.Items[TotCTIndex].SubItems[1].Text = TotCatch.ToString();
			listView2.Items[TotCTIndex].SubItems[2].Text  = pE.ToString()+" %";
			listView2.Items[TotCTIndex].SubItems[3].Text = pR.ToString()+ " %";
			//listView2.Items[TotCTIndex].SubItems[4].Text = pF.ToString()+ " %";
			listView2.Items[TotCTIndex].SubItems[4].Text = pN.ToString()+" %";
			listView2.Items[TotCTIndex].SubItems[5].Text = pRe.ToString()+" %";

			/*
			//Write to file
			string strTemp = outfile.FullName;
			if(strTemp.IndexOf(".txt")>0)
				strTemp = strTemp.Replace(".txt",".dat");
			else
				strTemp += ".dat";
			output = new StreamWriter(strTemp,true);
			foreach (ListViewItem li in listView2.Items)
			{
				for(int i=0;i<li.SubItems.Count;i++)
				{
					str.Append(li.SubItems[i].Text);
					str.Append('\t');
				}
				str.Append(System.Environment.NewLine);
			}
			output.WriteLine(str.ToString());

			output.Flush();
			output.Close(); */
		}
		private void WriteToFile()
		{
			//Write to file
			StringBuilder str = new StringBuilder();
			string strTemp = outfile.FullName;
			if(strTemp.IndexOf(".txt")>0)
				strTemp = strTemp.Replace(".txt",".dat");
			else
				strTemp += ".dat";
			output = new StreamWriter(strTemp,true);
			str.Append("Stim \t   #Played   #EBW    #RBW     #NFC    #NIL	#Repeat");
			str.Append(System.Environment.NewLine);

			foreach (ListViewItem li in listView2.Items)
			{
				for(int i=0;i<li.SubItems.Count;i++)
				{
					str.Append(li.SubItems[i].Text.Trim());
					str.Append('\t');
					if(i==0)str.Append('\t');
				}
				str.Append(System.Environment.NewLine);
			}
			output.WriteLine(str.ToString());

			output.Flush();
			output.Close();
		}
		private void WriteEachStimToFile()
		{
			//Write to file
			StringBuilder str = new StringBuilder();
			string strTemp = outfile.FullName;
			if(strTemp.IndexOf(".txt")>0)
				strTemp = strTemp.Replace(".txt",".dat");
			else
				strTemp += ".dat";
			output = new StreamWriter(strTemp,true);

			ListViewItem li = listView1.Items[listView1.Items.Count-1];
			for(int i=0;i<li.SubItems.Count;i++)
			{
				str.Append(li.SubItems[i].Text);
				str.Append('\t');
			}
			
			str.Append(System.Environment.NewLine);
			
			output.WriteLine(str.ToString());
			output.Flush();
			output.Close();
		}
		private int GetLevel(Run R)
		{
			double d = mainmenu.CalDb;
			double fLevel = R.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(R.CurrentStim.strType!="wave")
			{
				V2 = mainmenu.GetV2(R.nCurrentLevel,R.CurrentStim.nFreq,R.CurrentStim.strEar);
			}
			return V2;
		}
#endregion

		#region Event Handlers
		private void timerPlay_Tick(object sender, System.EventArgs e)
		{
			timerPlay.Stop();//dont need more ticks until we are done.
			if(bEnableCatchTrial)//for catch trial enabled sessions
			{//if this run is a catch trial
				if(iPlayCount  >= StimCount*CombinStims*mainmenu.def.nReps +iTotCatchNum)
				{//return when done
					WriteToFile();
					MessageBox.Show("Game Complete.");
					return;
				}
			}
			else if (iPlayCount >= StimCount * CombinStims*mainmenu.def.nReps){ //return when done
				WriteToFile();
				MessageBox.Show("Game Complete.");
				return;
			}
			try
			{
				if(!player.ibolArscRunning)
				{  pcGame.iRepeatCount=0;
					PlayInRandomPair();
				//	WriteResult();
				}
			}
			catch(Exception ex){} ;
		}
		private void mnuSelectFolder_Click(object sender, System.EventArgs e)
		{
			FolderBrowserDialog fbd = new FolderBrowserDialog();
			if(fbd.ShowDialog()==DialogResult.OK)
			{
				m_strFolderPath = fbd.SelectedPath;
				sbpFolder.Text = m_strFolderPath;
				if(CreateFileLists(m_strFolderPath)){
				}
					
			}
		}
		private void btnReset_Click(object sender, System.EventArgs e)
		{
			if(Primary == null) return;
			if(player.ibolArscRunning) return;
			listView1.Clear();
			listView2.Clear();
			InitView();
			InitStims();
			iPlayCount=0;
			bPaused=false;
			ClearTextboxes();
//			Primary.nCurrentGame = 0;
			pcGame.SetupGame(mainmenu.def.strFeedbackDir,(string) mainmenu.def.Feedback[Primary.nCurrentGame]);		
			bPlayInProgress = false;
			DC.Clear();
			timerPlay.Stop();
		}

		private void btnPause_Click(object sender, System.EventArgs e)
		{
			Button b = (Button ) sender;
			if (b.Text.Equals("Pause"))
			{
				timerPlay.Stop();
				bPaused = true;
				b.Text="Resume";
				return;
			}
			else if(b.Text.Equals("Resume"))
			{
				timerPlay.Start();
				bPaused = false;
				b.Text="Pause";
				return;
			}
		}
		private void pcGame_ButtonEvt(object sender, EventArgs e)
		{
			if(Primary == null || Secondary==null) return;
			// if sound is playing, dont do anything
			if (player.ibolArscRunning ||bPlayInProgress) return;
			//stop timer while we process the response
			timerPlay.Stop();
			
			string strButton = pcGame.strButtonClicked.ToLower();
	
			switch(strButton)
			{
				case "3": 
					Primary.CurrentResponse="NIL"; // No difference pressed	
					pcGame.iRepeatCount++;
					break;
				case "1":
					Primary.CurrentResponse=Primary.CurrentStim.strInfo;
					pcGame.iRepeatCount++;
					break;
				case "2":
					Primary.CurrentResponse=Secondary.CurrentStim.strInfo;
					pcGame.iRepeatCount++;
					break;
				case "repeat": //play previous signals
					Primary.CurrentResponse="Repeat";
					Primary.strAction="Repeat";
					WriteResult();
					PlayStreams(Primary.CurrentStim.buffer,Secondary.CurrentStim.buffer);
					return;
			}
			Primary.strAction=strButton; 
			WriteResult();
			if(iPlayCount % mainmenu.def.nChangeFeedback ==0)
			{
				if(pcGame.Step(true)==false)
				{
					DialogResult r = MessageBox.Show("Play another game? ","Game Complete",MessageBoxButtons.YesNo,MessageBoxIcon.Exclamation);
					if(r==DialogResult.Yes)
					{
						Primary.nCurrentGame++;
						if(Primary.nCurrentGame==mainmenu.def.Feedback.Count)
							Primary.nCurrentGame=0;
						pcGame.SetupGame(mainmenu.def.strFeedbackDir,(string) mainmenu.def.Feedback[Primary.nCurrentGame]);		
						timerPlay.Start();
					}
					else
						timerPlay.Stop();
					return;
				}
				pcGame.game.BlankScreen(false);//bring the picture on
			}
		//	pcGame.Refresh();
			bPlayInProgress = false;
			if(!bPaused) timerPlay.Start();
			//restart timer
		}
		private void pcGame_KeyEvt(object sender, KeyPressEventArgs e)
		{
			EventArgs ev = new EventArgs();
			switch(e.KeyChar)
			{
				case 's':
				case 'S':
					btnPause_Click(sender,ev);
					break;
				case 'p':
				case 'P':
					btnPlay_Click(sender, ev);
					break;
				
			}
		}
		private void PairedComparison_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			if(player.ibolArscRunning) return;
			if(pcGame != null)
			{
				pcGame.Close();
				pcGame.Dispose();
			}
		}
		private void btnPlay_Click(object sender, System.EventArgs e)
		{
			if(iPlayCount>0) 
			{
				MessageBox.Show("Game already in play. Reset and Play to start a new game.");
				return;
			}
			dtStart = DateTime.Now;
			bPaused = false;
			timerPlay.Start();
		}
		private void timerPulse_Tick(object sender, System.EventArgs e)
		{//Use pulse timer for any other timer services
		
			if(!bPlayInProgress) // for fading feedback pic after certain time
			{
				//TimeSpan diff = DateTime.Now.Subtract(LastPlayMoment);
				//if(mainmenu.def.nFadeFeedback > 0) // if fadefeedback is enabled
					//if(diff.TotalMilliseconds > (PLAY_INTERVAL+INTER_STIM_INTERVAL+mainmenu.def.nFadeFeedback))
						//pcGame.game.FadeScreen(); 
			}// end if fade feedback

		 
		}
		private void btnGenReport_Click(object sender, System.EventArgs e)
		{
			WriteToFile();
		}

		private void btnEditCatch_Click(object sender, System.EventArgs e)
		{
			if(iPlayCount != 0)
			{
				MessageBox.Show("Please Reset the game and change this value.");
				return;
			}
			if(!bEnableCatchTrial)
			{
				MessageBox.Show("Not applicable when catch trials are disabled.");
				return;
			}
			if(btnEditCatch.Text.ToLower().Equals("edit"))
			{
				txtCatchTrials.ReadOnly=false;
				btnEditCatch.Text="Apply";
			}
			else if(btnEditCatch.Text.ToLower().Equals("apply"))
			{
				txtCatchTrials.ReadOnly=true;
				btnEditCatch.Text="Edit";
				try
				{	
					iTotCatchNum = int.Parse(txtCatchTrials.Text);
					if(iTotCatchNum > StimCount*CombinStims*mainmenu.def.nReps) iTotCatchNum=(int)Math.Round(StimCount*CombinStims*mainmenu.def.nReps);
					mainmenu.def.nCatchFreq = (int)Math.Round((double)iTotCatchNum*100.0/(iTotCatchNum+StimCount*CombinStims*mainmenu.def.nReps),0);
					iCatchTrialInterval = (int)Math.Round((double)(iTotCatchNum+StimCount*CombinStims*mainmenu.def.nReps)/iTotCatchNum);

					ClearTextboxes();
					txtCatchTrials.Text = iTotCatchNum.ToString();
					txtCatchPC.Text = mainmenu.def.nCatchFreq.ToString()+ " %";
				}
				catch(Exception){}
			}
		}
		#endregion 
		public void Test()
		{
			try
			{
				//PlayAtRandom();
			}
			catch (Exception e){MessageBox.Show(e.Message);}
		}

		private void button2_Click(object sender, System.EventArgs e)
		{
			pcGame.game.FadeScreen();
		}

		
	}
}
