//Brain Trainer

var VERSION           = "044";

//PARAMETERS
var defaultDelaySecs  = 2.5;
var defaultnRuns      = 20;
var matchProbability  = 0.5;//probability that box or content matches one
var requiredBoxes     = 4;
var mainWidth         = 765;//must agree with stylesheet 

var initialDelayMs   = 500; //time to first display
var boxSize           = 80;  //grid
var nFontColor        = "#c03030"; //numbers in box
var gridLeft          = 0;
var blankMs           = 200;//time gap between numbers
var displayMs         = 0;//time for which content is displayed
var showAllBoxMs      = 500;
var nHistoryFields    = 8;
var hFieldSize        = 10;
var hShortFieldSize   = 6;

//DERIVED PARAMS
var fontSize          = boxSize - 10;  //grid

//CONSTANTS
var NOTHING           = 0;//tast
var RUNNING           = 1;//task
var TESTING           = 2;//task
var SAMEKEY           = 83; //"S"
var DIFFERENTKEY      = 68; //"D"
var ESCAPEKEY         = 27;
var SPACEBAR          = 32;
var USE_POPUP_HELP    = 0;

var sym = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","0","P","Q","R","S","T","U","V","W","X","Y","Z"];
var nContentValues    = sym.length;


//GLOBAL VARIABLES

//Arrays
var contentIndex = null; //contentIndex[t] = index i of sym[i] and keyCode[i] changed at time t
var boxChanged = null;   //boxChanged[t] = box whose contentIndex is changed at time t
var response = null;
var boxInitialContentIndex = null;
var sameAsBefore = null;
var hst = null; 

//scalars
var DOING = NOTHING;//task variable
var periodMs = 0; //time between displays
var nBoxes = 0;//global
var nMatches = 0;
var positionInSequence=0;
var currentIndex = 0;
var nJobs = 0;
var nLetsPerRun = 0;  //nJobs = nBack + nLetsPerRun
var abort = false;
var lastDoneAtMs = 0;
var maxscore = 0.0;
var reportStr = "";
var nAttempts=0;
var quicktest = 0;
var n11=0;//match and claim (correct)
var n01=0;//no match and claim (incorrect)
var n10=0;//match and no claim (incorrect)
var n00=0;//no match and no claim (correct)

function initspecial()
{
hst = new Array();
writeMenu();
writeMain();
writeGrid();
document.getElementById("c_main").focus();
}

function quickTest()
{
quicktest = 1;
runTest();
}

//string specifying drop-down list
function dropDownListStr(id,label,list,deflt,onch)
{
var s = '<p><select id = "' + id + '" class="c_sbox" onchange = "XXX">\n'
s = s.replace(/XXX/g,onch);
for (var j=0;j<list.length;j++)
  {
  if (deflt == j) s += '<option value="' + list[j] + '" selected>' + list[j] + '</option>\n';
  else s += '<option value="' + list[j] + '">' + list[j] + '</option>\n';
  }
s += '</select> ' + label + '</p>\n';
//alert(s)
return s;  
}

//content of c_main = grid area, flash message area, score area, copyright
function writeMain()
{
var s='<div id="gridDivId"></div>\n' //grid will go here written by writeGrid()
+'<br>'
+'<div id="msgid" style="vertical-align:middle;text-align:center;height:20px;"></div>' //for flash messages
+'<div id="scoreid"></div>\n' //for reportStr
+'<p class="c_copyright">&copy; John Gordon 2009' + spaces(10) + 'Version ' + VERSION + '</p>\n'
document.getElementById("c_main").innerHTML = s;
}


function writeGrid()
{
nBoxes = 0;
requiredBoxes = getInt(document.getElementById("nboxid"));

var rowSizeTable 
= [0,1,2,3,4,5,3,7,4,3,5,11, 4];
// 0 1 2 3 4 5 6 7 8 9 0 11 12

var rowSize = rowSizeTable[requiredBoxes];

var nRows = requiredBoxes/rowSize;

  function boxstr()
  {
  var tstr ='<td style="vertical-align:middle;text-align:center;height:XXXpx;width:XXXpx;font-size:FFFpx;color:CCC;border:solid 1px #a0a0ff">'
  + '<div id="boxNNN"><br></div></td>';
  tstr = tstr.replace(/XXX/g,boxSize).replace(/FFF/g,fontSize).replace(/CCC/g,nFontColor).replace(/NNN/,nBoxes);
  nBoxes += 1;
  return tstr;
  }
  
  function rowstr(boxPerRow)
  {
  var tstr ='<tr>';
  for (var j=0;j<boxPerRow;j++) tstr += boxstr();
  tstr += '</tr>\n' 
  return tstr;
  }
  
gridLeft = Math.floor(0.5*(mainWidth - rowSize*boxSize));
  
var tablestr = '<table style="position:relative;left:' 
+ gridLeft + 'px;border:solid 1px #a0a0ff" border="0" cellpadding="0" cellspacing="0"><tbody>';
for (var r = 0;r<nRows;r++) tablestr += rowstr(rowSize);
tablestr += '</tbody></table>\n';

var s = '<br><br><h2 style="font-size:14px;text-align:center">Spacebar=Start' 
+ spaces(15) + 'ESC=Abort' + spaces(15) + 'Any other key=Match found' + '</h2>\n'
+ '<br>' + tablestr;

document.getElementById("gridDivId").innerHTML = s;
document.getElementById("scoreid").innerHTML = "";
flashMsg("<p>Ready</p>");
}//writeGrid


function bigButStr(labl,clik)
{
return '<p style="text-align:center">'
+'<input type="button" style="width:100%;height:40px;font-size:20px;"'
+' value="'+labl+'" onclick="' + clik + '"></p>\n';
}

function writeMenu()
{
var s=''
+ bigButStr("Help","help()")
+ bigButStr("Start","runTest()")
+ bigButStr("Abort","doAbort()")
+'<br>\n'
+'<div class="SHADED">SETTINGS</div>\n'
+dropDownListStr("nboxid","Boxes",[3,4,5,6,8,9,10,12],2,"writeGrid()") + '\n'
+dropDownListStr("runsid","Letters",[5,10,15,20,25,30,40,50,60,70,80,90,100],4,"") + '\n'
+dropDownListStr("delayid","Seconds",["0.5","1.0","1.5","2.0","2.5","3.0","3.5","4.0"],4,"") + '\n'
+'<div id = "testid"></div>\n'
+'<br><hr>\n'
+'<p>Progress</p>\n'
+'<div id="progbar"></div>\n'
+'<p>Score</p>\n'
+'<div id="scorebar"></div>\n'
//+'<p style="color:#808080"><a href="javascript:insertTestMenu()">.</a></p>\n'
+'<a href="javascript:insertTestMenu()"><span style="color:#c0c0c0">.</span></a>\n'
document.getElementById("c_menu").innerHTML =s;
showProgress("progbar",0.0);
showProgress("scorebar",0.0);
}




//function clearbox(n){var bstr = "box" + n;document.getElementById(bstr).innerHTML="<br>";}

function clearbox(n){document.getElementById("box"+n).innerHTML="<br>";}


function clearGrid(){for (var j=0;j<nBoxes;j++) clearbox(j);}

//function writebox(n,txt){var bstr = "box" + n;document.getElementById(bstr).innerHTML=txt;}
function writebox(n,txt){document.getElementById("box"+n).innerHTML=txt;}

//write symbol into box
function pulseBox(n,txt,ms)
{
writebox(n,txt);
window.setTimeout('clearbox('+n+')',ms)
}

function randi()
{
return Math.floor(0x8FFFFFFF*Math.random());
}




function makeRandomSequence()
{
var boxPrevContentIndex = new Array(nBoxes);
var boxCurrentContentIndex = new Array(nBoxes);
boxChanged = new Array(nJobs);
response = new Array(nJobs);
contentIndex = new Array(nJobs);
sameAsBefore = new Array(nJobs);
boxInitialContentIndex = new Array(nBoxes);
n00=n01=n10=n11=0;
nMatches = 0;


nMatches = Math.floor(matchProbability*nJobs + 0.5)

for (var t=0;t<nMatches;t++) sameAsBefore[t] = 1;
for (var t=nMatches;t<nJobs;t++) sameAsBefore[t] = 0;

for (var j=nJobs-1;j>0;j--)
  {
  var k = randi() % (j+1);
  var t = sameAsBefore[j];
  sameAsBefore[j] = sameAsBefore[k];
  sameAsBefore[k] = t;
  }

//var s="";for (var j=0;j<nJobs;j++) s += NF(sameAsBefore[j],5,0);alert(s)

for (var b=0;b<nBoxes;b++) 
  {
  //preload all boxes
  boxCurrentContentIndex[b] = randi() % nContentValues;
  boxInitialContentIndex[b] = boxCurrentContentIndex[b]; 
  boxPrevContentIndex[b] = -1;
  }

var b = -1, c = -1;

//set up actual boxChanged[] and contentIndex[] values
for (var t=0;t<nJobs;t++)
  {
  if ((b>=0) && (nBoxes > 2)) //don't pick same box as before
    {
    var bb = randi() % nBoxes;
    while (bb == b) bb = randi() % nBoxes;
    b = bb;
    }
  else b = randi() % nBoxes;//the box we're going to change
  
  if (sameAsBefore[t] > 0) c = boxCurrentContentIndex[b];
  else c = randi() % nContentValues;//its new value
 // if (randomFloat() < matchProbability) c = boxCurrentContentIndex[b];
 // else c = randi() % nContentValues;//its new value
  boxPrevContentIndex[b] = boxCurrentContentIndex[b];
  boxCurrentContentIndex[b] = c;
  
  boxChanged[t] = b;
  contentIndex[t] = c;
  response[t] = -1;
  }
}




//actually do the test
function runTest()
{
if (DOING == RUNNING) return;
DOING = RUNNING;
//get paramete4rs
nLetsPerRun = getInt(document.getElementById("runsid"));
periodMs = Math.floor(1000*getFloat(document.getElementById("delayid")));

//fill c_main
writeMain();

//add the grid to it
writeGrid();

//clear bars
showProgress("progbar",0.0);
showProgress("scorebar",0.0);

if (quicktest){periodMs = 50;}

blankMs = Math.floor(0.25*periodMs + 0.1);

displayMs = periodMs - blankMs;//time for which content is displayed

nJobs = nLetsPerRun;

//make the sequence
makeRandomSequence();

//start it running
positionInSequence=0;
currentIndex = 0;
abort = false;
nAttempts = 0;

var t1 = showAllBoxMs*nBoxes;
var t2 = initialDelayMs;

if (quicktest){t1=50;t2=50;}

//show the initial box content
for (var b = 0;b<nBoxes;b++) pulseBox(b,sym[boxInitialContentIndex[b]],t1);

//hand over to sequencer
window.setTimeout("nextInSequence()",t1+t2);
}


//the sequencer
function nextInSequence()
{
//abort?
if (abort) 
  {
  clearGrid();
  showProgress("progbar",0.0);
  showProgress("scorebar",0.0);
  quicktest = 0;
  DOING = NOTHING;
  return;
  }

//finished?  
if (positionInSequence>=nJobs) 
  {
  clearGrid();
  showProgress("progbar",0.0);
  showProgress("scorebar",0.0);
  showScore();
  quicktest = 0;
  DOING = NOTHING;
  return;
  }

//this is the only place where a box content is written

var bx = boxChanged[positionInSequence];
var cn = contentIndex[positionInSequence];
//boxPrevContentIndex[bx] = boxCurrentContentIndex[bx];
//boxCurrentContentIndex[bx] = cn;
pulseBox(bx,sym[cn],displayMs);

lastDoneAtMs = msecs();//note present time
currentIndex = positionInSequence;
positionInSequence++;

if (quicktest)
  {
  var p = 0.75;//prob of getting it right
  
  if (Math.random() < p)//give correct reply
    {
    if (sameAsBefore[currentIndex]) actOnKey(SAMEKEY);
    }
  else //give incorrect reply
    {
    if (sameAsBefore[currentIndex]==0) actOnKey(SAMEKEY);
    }  
  }//if quicktest
    
showProgress("progbar",1.0*positionInSequence/nJobs);

showProgress("scorebar",score(0));

var nextMs = lastDoneAtMs + periodMs; //calculate time for next display
var delayMs = nextMs - lastDoneAtMs; //and hence the delay till then
window.setTimeout("nextInSequence()",delayMs);//and set it in motion
}



//called by keyHandle(e) and also called directly
function actOnKey(k)
{
//if not RUNNING only SPACEBAR operates

if (DOING != RUNNING)
  {
  if (k==SPACEBAR) runTest();
  return;
  }

else if (DOING == NOTHING) return;

else if (DOING == TESTING){showKey(k);return;}

else if (DOING == RUNNING)//ESC aborts, anything else signal match
  {
  
  if (k==ESCAPEKEY) {doAbort();return;}
  
  if (response[currentIndex] > 0) return;//only 1 reply permitted
  
  response[currentIndex] = 1;
  
  if (sameAsBefore[currentIndex]){flashColr("CORRECT","green");}
  else {flashColr("WRONG","red");n01++;}

  nAttempts++;
  }

}

function keyHandle(e)
{
var k;
if(window.event) k = e.keyCode; // IE
else if(e.which) k = e.which;// Netscape/Firefox/Opera
actOnKey(k)
}


function flashMsg(msg)
{
document.getElementById("msgid").innerHTML = msg; 
window.setTimeout('document.getElementById("msgid").innerHTML = ""',1000);
}

function flashColr(msg,colr)
{
flashMsg('<span style="color:' + colr + ';font-weight:bold;text-align:center";>' + msg + '</span>')
}

function doAbort(){abort = true;flashMsg("<p>aborted</p>");}

function showScore()
{
score(1);
document.getElementById("scoreid").innerHTML = reportStr;
}


function score(report)
{
n00 = n01 = n10 = n11 = 0;
for (var j=0;j<nJobs;j++) 
  {
  var match=0,claim=0;
  if (sameAsBefore[j] > 0) match = 1;
  if (response[j] > 0) claim = 1;
  var nn = 2*match + claim;
  if (nn == 0) n00++;
  if (nn == 1) n01++;
  if (nn == 2) n10++;
  if (nn == 3) n11++;

  }
var tot = n11 + n00 - n01 - n10;
if (tot < 0.0) tot = 0.0;
x = 1.0*tot/(1+currentIndex);
if (report)
  {
  var percent=100.0*tot/(1+currentIndex);
  s=''
  +'<p></p>'
  +'<p>You scored F1 out of F2 as follows.</p>'
  //+'<p>There were F3 matches and you claimed F4.</p>'
  +'<p>You scored F5 for correctly claiming matches (column A below) and F6 for correctly not-claiming non-matches (B).</p>'
  +'<p>You lost F7 for incorrectly claiming non-matches (C) and lost F8 for matches you missed (D).</p>';
  
  s=s.replace(/F1/,tot);
  s=s.replace(/F2/,(1+currentIndex));
  //s=s.replace(/F3/,nMatches);
  //s=s.replace(/F4/,nAttempts)
  s=s.replace(/F5/,n11);
  s=s.replace(/F6/,n00);
  s=s.replace(/F7/,n01);
  s=s.replace(/F8/,n10);

  reportStr = s;

  hst[hst.length] = NF(percent,hFieldSize,1); 
  hst[hst.length] = NF(nBoxes,hFieldSize,0);
  hst[hst.length] = NF(nLetsPerRun,hFieldSize,0);
  hst[hst.length] = NF(0.001*periodMs,hFieldSize,2); 
  hst[hst.length] = NF(n11,hShortFieldSize,0); 
  hst[hst.length] = NF(n00,hShortFieldSize,0); 
  hst[hst.length] = NF(-n01,hShortFieldSize,0); 
  hst[hst.length] = NF(-n10,hShortFieldSize,0); 
 
  reportStr = '<h3>Run ' + NF(hst.length/nHistoryFields,1,0) + spaces(8) + 'Score=' + NF(percent,1,1) + '%</h3>' + reportStr + historyStr() + '\n'; 
 
 }
return x;
}


function historyStr()
{
var n = hst.length/nHistoryFields;
var k=0;

//var s= '       Run     Boxes   Letters      Secs     Score     A     B     C     D\n';
var s= '<pre style="color:#c00000;">';
s += '       Run     Score     Boxes   Letters      Secs     A     B     C     D';
s += '</pre><pre style="color:#4040c0">';

for (var j=0;j<n;j++)
  {
  s += NF(j+1,hFieldSize,0);//run
  for (var f=0;f<nHistoryFields;f++) s += hst[k++];
  s += '\n';
  }
s += "</pre>"  
return s;  
}


function showHistory()
{
writeMain();
document.getElementById("gridDivId").innerHTML = "<pre>\n" + historyStr() + "\n</pre>"; 
}


function help()
{
var s = '<h1>Brain Trainer</h1>\n'
+'<div style="font-size:14px">\n'
+'<p>There is evidence that this type of game improves both working memory and concentration.</p>\n'
+'<h3>How to play</h3>\n'
+'<p>To start the test click the Start button on the left or press the space bar.</p>\n'
+'<p>Letters will appear simultaneously in all the boxes for a while before disappearing.</p>\n'
+'<p>Then a random letter will appear for a second or two in a random box, then another random letter in another random box, and so on. \n'
+'Each time this happens, if the random letter is the same as the PREVIOUS content of the SAME box press any key (except ESC),'
+' otherwise do nothing. That\'s all there is to it.</p>\n'
+'<p>The test will stop automatically after about a minute (depending on the settings) and you\'ll be presented with your score.</p>\n'
+'<p>You can halt the test at any time by pressing the ESC key or clicking the Abort button on the left, but you won\'t be given a score.</p>\n\n'
+'<h3>Subtlety</h3>\n'
+'<p>However there\'s a subtlety you\'ll quickly discover. Each time a letter appears in a box it will be either'
+' the same as the previous content, or different.  If it\'s the same you just press a key.'
+' But if it\'s different you need to forget the previous content and memorize the new letter because that\'s the one you\'ll be comparing with next time,'
+' and that\'s what trains your working memory.</p>\n' 
+'<h3>Scoring</h3>\n'
+'<p>You gain a point for correctly claiming a match or for correctly not-claiming a non-match. You lose a point for missing a match or for claiming a match when there isn\'t one.</p>'
+'<h3>Settings</h3>'
+'<p>On the panel on the left you can change the number of boxes shown, the number of letters per run, and the seconds that each letter is displayed for.</p>\n'
+'<h3>Tips</h3>'
+'<p>Improvement is best achieved if you choose slightly more boxes than you\'re comfortable with - but only slightly more. \n'
+' Don\'t worry if you need to start with just 2 or 3 boxes, you\'ll soon improve.'
+' Try increasing the difficulty as you get better. It\'s a good idea to keep a note of your progress. </p>\n'
+'<p>It\'s best not to try to work out strategies such as repeating the letters silently to yourself, \n'
+'but just to let your mind find its own way of improving, even though this can be frustrating. You\'ll find that \n'
+'success depends as much on avoiding distraction as it does on memorizing.</p>\n'
+'<p>However if you practice (for about 20 minutes a day) you should notice a lot of progress over a period of weeks \n'
+' (which is why you\'ll be pleased you kept a record), and the improvement should carry over to many other activities. \n'
+'You should soon find you feel more alert and bright.</p>\n';

if (USE_POPUP_HELP) 
  {
  s += '<p style="text-align:center"><a href="#" onclick="window.close()">CLOSE</a></p></div>\n';
  popup(s,800,700);
  }
  
else 
  {
  s += '<p style="text-align:center"><a href="#" onclick="writeMain();writeGrid()">CLOSE</a></p></div>\n';
  document.getElementById("c_main").innerHTML = s;
  }
}




function testShow()
{
var s="<p>Lorem ipsum dolor sit amet consectetuer Sed Nunc consequat cursus justo. Nullam est interdum consectetuer quis faucibus Maecenas Praesent id nulla ut. Ultrices malesuada lacus quis semper libero et felis Nam semper et. Fringilla tempus dolor odio cursus interdum amet fringilla mauris iaculis vitae. Sollicitudin Pellentesque quis diam orci vitae nibh ullamcorper orci porttitor Vestibulum. Amet wisi ut orci.</p>"
+"<p>Sed ipsum condimentum justo dapibus Donec sociis at pretium libero netus. Curabitur fringilla id congue accumsan tellus ac dolor turpis nec lacus. Morbi auctor et Vestibulum ipsum Nulla elit laoreet turpis Donec elit. Non consequat tellus tortor Curabitur sem tortor condimentum tristique leo lorem. Sed est habitasse non Suspendisse quis tortor arcu.</p>"
+"<p>Fringilla malesuada in malesuada interdum ligula tristique consequat fringilla ut Nunc. Lacus Curabitur Nam nec et arcu mi molestie nonummy Vestibulum non. Convallis auctor leo orci mauris Duis Nulla sed tincidunt nibh in. Nec lacus Mauris Ut interdum quis urna tempor orci Vestibulum dignissim. Et massa lorem lobortis nunc eu Pellentesque pretium Nulla Nunc parturient. Sagittis.</p>"
showInNewWindow(s,"lorem",100,100,500,500,0,0);
}





function insertTestMenu()
{
var e = document.getElementById("testid");
if (e.innerHTML == "") e.innerHTML = ''
+'<div class="SHADED">TESTS</div>'
+'<p><a href="javascript:quickTest();">Quick simulation</a></p>'
+'<p><a href="javascript:showScore();">report</a></p>'
+'<p><a href="javascript:testShow();">test show</a></p>'
+'<p><a href="javascript:;"></a></p>'
+'<p><a href="javascript:showHistory();">history</a></p>'
//+'<p><a href="javascript:;"></a></p>'
;
else e.innerHTML = "";
}


function showProgress(id,x)
{
var WIDTH = 100;
if (x > 1.0) x = 1.0;
if (x < 0.0) x = 0.0;
var barWidth = NF(1.0*WIDTH*x,2,0);
var s = '<div style="border:solid 1px #000000;width:' + WIDTH + 'px;position:relative;left:8px;">'
 +'<table border="0" cellpadding="0" cellspacing="0">'
 +'<tbody><tr style="height:14px;">'
 +'<td style="background:#9090ff;" width="' + barWidth + 'px";></td>'
 +'<td style="background:#808080;"></td>'
 +'</tr></tbody></table></div>';
//s = s.replace(/AAA/,barWidth);
//alert(s)
document.getElementById(id).innerHTML = s;
}

//NF(number, fieldsize, decimals);
//number format with leading spaces
function NF(number, fieldsize, decimals)
{
var t;
if (!isNaN(number)) t = number.toFixed(decimals); else t = "-";
var L = fieldsize - t.length;
while (L-- > 0) t = ' ' + t;
return t;
}


//getInt(F.box) = integer from F.box.value
function getInt(x)
{
if (x.value == "-") return 0;
if (x.value == "") return 0;
var v = parseInt(x.value);
if (isNaN(v)) {alert("Invalid integer string: '" + x.value + "' so using zero instead");return 0;}
return v;
}

//n repeats of ch
function repeats(ch,n)
{
var s = "";
while (n-- > 0) s += ch;
return s;
}


//getFloat(F.box) = getFloat from F.box.value
function getFloat(x)
{
if (x.value == "-") return 0;
if (x.value == "") return 0;
var v = parseFloat(x.value);
if (isNaN(v)) {alert("Invalid float string: '" + x.value + "' so using zero instead");return 0;}
return v;
}


function spaces(n){return repeats("&nbsp;",n);}

function msecs(){var d = new Date();return d.getTime();}


function popup(txt,W,H)
{
var SW = screen.width;
var SH = screen.height;
showInNewWindow(txt,"",(SW-W)/2,(SH-H)/2,W,H,0,0);
}

//showInNewWindow(txt,title,left,top,width,height,menu,tools)
function showInNewWindow(txt,title,lf,tp,w,h,menu,tools)
{
var format="top=" + tp 
  + ",left=" + lf 
  + ",width=" + w 
  + ",height=" + h 
  + ",scrollbars=1"
  + ",menubar=" + menu 
  + ",toolbar=" + tools
  + ",location=0"
  + ",directories=0"
  + ",status=0" 
  + ",resizable=1";
//alert(format)
//OPEN FOR WRITING
var win2 = window.open("","",format); if (win2 == null) {alert("cannot open new window");return;}

//WRITE STYLE FOR SECONDARY DOCUMENT
var T = "<html><head><title>" + title + "</title>"
+"\n<style type='text/css'>"
+"\nbody{font-family:arial,helvetica,sans;font-size:12px;color:#303030;}"
+"\np{margin:5px 2px 5px 2px;}"
+"\nh1,h2,h3,h4,h5,h6{color:#4040c0;font-style:normal;margin:2px 3px 3px 2px}"
+"\nh1{font-size:24px;}"
+"\nh2{font-size:20px;}"
+"\nh3{font-size:16px;}"
+"\npre{font-family:Courier New; font-size:11px; color:black; margin:0px 0px 0px 2px;}"
+"\n<\/style>\n</head>\n"
+ txt
+"\n<script>self.focus();<\/script>"
+"\n<\/body><\/html>";

//INSERT INTO DOCUMENT
win2.document.write(T);
win2.document.close();//or you won't see it
}//showInNewWindow
