var recording=false;
var lasttime=0;
var playing=0;
var stamp;
var step=0;
var file="untitled";
var prevDelay=0;
var prevStart=0;
var prevEnd=0;
var prevKey=0;
var selected=false;
var graph=[];
var debugCount=0;
var totalTime=0;
var elapsedTime=0;
var frames;
var fontSize=16;
var prevTime=-1;
var tTime=0;
var playbackText="";
var playFrame=0;
var session;
var speed=4;
var lastFramePlayed=0;
var masterText;
var domain=document.domain;
var threadCount=1;
var data;
var autoplay;
var security=1;
var fileid="";
var password="";
var auth="";
var author;

browser=navigator.appName;
check=browser.indexOf("Microsoft");
if (check!=-1) {

	alert("You appear to be using Microsoft Internet Explorer. Please get Firefox.");
	location.href="http://www.getfirefox.com";

}




function onKeyDown(event)
{
				
	if (!recording) 
		return;
		
		
	var now = new Date();
	curtime = now.getTime();
	
	if (lasttime==0) 
		delay=0;
	else 
		delay=curtime-lasttime;
	

	lasttime=curtime;

	curStart=document.getElementById("page").selectionStart;
	curEnd=document.getElementById("page").selectionEnd;
	masterText=document.getElementById("page").value;
	if (appendText(step,prevDelay,masterText,prevStart,prevEnd,curStart,curEnd,prevKey)) {
		prevDelay=delay;
	} else {
		prevDelay+=delay;
	}
	
	prevStart=curStart;
	prevEnd=curEnd;
	prevKey=event.keyCode;
	
	step++;


	if (event.keyCode == 9) {

		globalvar = document.getElementById("page"); 
		setTimeout("globalvar.focus()",10);
		
	}

}




function updateWordCount() {
	txt=document.getElementById("page").value;
	document.getElementById("count").innerHTML=wordCount(txt);
}


function wordCount(str) {
	char_count = str.length;
	fullStr = str + " ";
	initial_whitespace_rExp = /^[^A-Za-z0-9]+/gi;
	left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
	non_alphanumerics_rExp = rExp = /[^A-Za-z0-9]+/gi;
	cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
	splitString = cleanedStr.split(" ");
	word_count = splitString.length -1;
	return word_count;
}




function toggleRecordMode() {
	setRecordMode(!recording);
}


function setRecordMode(flag) {

	recording=flag;
	if (recording) {
		goToTime(500);
		setStatus("Recording");
		lasttime=0;
		enableControls(false);
		enableFileControls(false);
		document.getElementById("recordButton").value="Stop";
		
		if (data.length!=0) {
			var now = new Date();
			lasttime = now.getTime();
		}
		
		enablePage();
		
	} else {
		document.getElementById("page").disabled=true;
		document.getElementById("recordButton").value="Record";
		if (data.length==0) return;
		
		curStart=document.getElementById("page").selectionStart;
		curEnd=document.getElementById("page").selectionEnd;
		masterText=document.getElementById("page").value;
		appendText(step,prevDelay,document.getElementById("page").value,prevStart,prevEnd,curStart,curEnd);
		prevDelay=0;
		setStatus("Syncing");
		getFrames();
		setLength(totalTime/1000);
		setStatus("Idle");
		lastFramePlayed=0;
		elapsedTime=0;
		enableControls();
		enableFileControls();
		
	}

}



function enablePage() {

		l=document.getElementById("page").value.length;
		document.getElementById("page").disabled=false;		
		document.getElementById("page").focus();
		document.getElementById("page").selectionStart=l;
		document.getElementById("page").selectionEnd=l;
		document.getElementById("page").focus();
		
}



function appendDocumentFrame() {

	pos=data.length;
	data[pos]=['x',totalTime,masterText];
	
}




function appendText(s,d,t,start,end,start2,end2,key) {
	
	previousLength=prev.length;
	newLength=t.length;
	selectionLength=end-start;
	deltaLength=newLength-previousLength;

	if (deltaLength==0 && t==prev) return false;


	pos=data.length;
	
	//Append Operation-- characters typed/pasted at very end
	if (selectionLength==0 && start==previousLength && deltaLength>0) {
		ch=t.substr(newLength-deltaLength,deltaLength);
		data[pos]=['a',d,ch];
	}
	
	//Insert Operation-- characters typed/pasted somewhere inside the document
	else if (selectionLength==0 && deltaLength>0) {
		ch=t.substr(start,deltaLength);
		data[pos]=['i',d,start,ch];
	}
	
	//Backspace Operation-- a single character is deleted before the cursor
	else if (selectionLength==0 && deltaLength==-1 && key==8) {
		data[pos]=['b',d,start];
	}
	
	//Delete Operation-- multiple characters are deleted, via cut, clear, backspace, or delete key
	else if ((selectionLength+deltaLength)<0) {
	
		if (key==46) {
			deleteTo=start-deltaLength;	
			data[pos]=['d',d,start,deleteTo];
		} else {
			deleteTo=end+deltaLength;	
			data[pos]=['d',d,deleteTo,end];
		}
		
	}
	
	//Replace operation
	else if (selectionLength!=0) {
		remainderLength=previousLength-selectionLength;
		addedLength=newLength-remainderLength;
		ch=t.substr(start,addedLength);
		data[pos]=['r',d,start,end,ch];
	}
	
	//Replace operation--occurs occasionally when multiple keys are pressed
	else if (selectionLength==0) {
	
		s=start2;
		while (t.substr(0,s)!=prev.substr(0,s)) {
			s--;
		}
		
		ch=t.substr(s,start2-s);
		data[pos]=['r',d,s,start2,ch];
		
		
	//Keyframe operation-- the failsafe
	} else {
		data[pos]=['k',d,t];
	}
	
	newText=getFrame(data[pos],prev);
	if (newText!=t) {
		
		s=start;
		e=prev.length-start;
				
		while (t.substr(0,s)!=prev.substr(0,s) && s>0) {
				s--;

		}
			
		while (t.substr(t.length-e,e)!=prev.substr(prev.length-e,e) && e>0) {
				e--;
		}
		
		ch=t.substring(s,t.length-e);
		data[pos]=['r',d,s,prev.length-e,ch];
		
		
		newText=getFrame(data[pos],prev);
		
		if (newText!=t) {	
			data[pos]=['k',d,t];
		} 
		
	}
	
	prev=t;
	return true;	
}


function startPlayback() {


	if (!playing) {
		document.getElementById("recordButton").disabled=true;
			document.getElementById("page").disabled=true;

		enableFileControls(false);
		playing=threadCount++;
		setStatus("Playing");
		document.getElementById("playButton").value="Stop";
		if (lastFramePlayed>data.length) 
		{
			goToTime(0);
			startPlayback();
			return;
		}
		playback(lastFramePlayed,playing);
	} else {
		
		stopPlayback();

	}

}


function stopPlayback() {
	if (recording) return;
	playing=0;
	setStatus("Idle");
	document.getElementById("playButton").value="Play";
	//document.getElementById("page").disabled=false;
	if (security!=0) document.getElementById("recordButton").disabled=false;
	enableFileControls();
}


function playback(frame,thread){


	elt=document.getElementById("page");

	if (playing!=thread) {
	 return;
	}

	setCurrentTime(elapsedTime/1000);

	if (frame==0)
		elt.value="";
	else
		elt.value=getFrame(data[frame-1]);
		
			lastFramePlayed=frame+1;

	if (frame>=data.length) {
		stopPlayback();
		elt.value=masterText;
	} else {
		stepdelay=framedelay=data[frame][1];
		elapsedTime+=framedelay;
				
		if (speed==-1) { 
			stepdelay=1;
		} else { 
			stepdelay=Math.ceil(stepdelay/speed);
			if (speed>1 && stepdelay>2000) stepdelay=2000;
		}
						
		window.setTimeout("playback("+(frame+1)+","+thread+")",stepdelay);
	}	

}



function changeSpeed(s) {
	speed=parseFloat(s);
}


function getFrame(frame,text) {


	playtype=frame[0];

	if (playtype=='k')
		return frame[2];

	if (text==null)
		text=document.getElementById("page").value;

	if (playtype=='a')
		return text+frame[2];

	if (playtype=='b') {
		cursorPos=frame[2];
		return text.substr(0,cursorPos-1)+text.substr(cursorPos,text.length-cursorPos);
	}

	if (playtype=='i') {
		cursorPos=frame[2];
		insertText=frame[3];
		return text.substr(0,cursorPos)+insertText+text.substr(cursorPos,text.length-cursorPos);		
	}

	if (playtype=='r') {
		cursorStart=frame[2];
		cursorEnd=frame[3];
		insertText=frame[4];
		return text.substr(0,cursorStart)+insertText+text.substr(cursorEnd,text.length-cursorEnd);
	}
	
	if (playtype=='d') {
		cursorStart=frame[2];
		cursorEnd=frame[3];
		return text.substring(0,cursorStart)+text.substr(cursorEnd,text.length-cursorEnd);
	}
	
	return "ERROR";

}



function setStatus(status) {

	var color="black";
	if (status=="Saving") color="green";
	if (status=="Recording") color="red";
	if (status=="Playing") color="blue";
	if (status=="Loading") color="purple";
	
	document.getElementById("status").innerHTML="<font color="+color+">"+status+"</font>";

}



var aJSONtext;



function saveFileServer() {

	setStatus("Saving");
	
	document.getElementById("_save").value="Saving...";
	document.getElementById("_save").disabled=true;
	document.getElementById("savestatus").innerHTML="<img src=indicator.gif>";
	
	var title2=document.getElementById("_title").value;
	var author2=document.getElementById("_author").value;
	var sec=document.getElementById("_security").value;
	var password2=document.getElementById("_password").value;
	var docLength=Math.floor(totalTime/1000);

	appendDocumentFrame();

	var myJSONText = JSON.stringify(data);
	data.splice(data.length-1,1);
	
	var url='http://'+domain+'/dlog/save2.php?title='+title2+'&author='+author2+"&time="+docLength+"&security="+sec;
	if (sec==1) url+='&password='+password2;
	if (fileid!="" && auth!="") url+="&id="+fileid+"&auth="+auth;
				
	xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=xmlhttpChange;
		
	xmlhttp.open('POST', url, true);
	xmlhttp.setRequestHeader('Content-Type', 'text/xml');
	xmlhttp.send(myJSONText);
	
	function xmlhttpChange()
	{
	// if xmlhttp shows "loaded"
	if (xmlhttp.readyState==4)
 	 {
 	 // if "OK"
  	if (xmlhttp.status==200)
  	  {
  	  
  	  	if (xmlhttp.getResponseHeader("Error")==1) {
  	  	
  			hideDialog();
    		alert("Error saving file. (Type 1)");
  			return;
  			
  	  	}
  	  	
  	  	
  	  	if (xmlhttp.getResponseHeader("Id")!="") {
  	  		fileid=xmlhttp.getResponseHeader("Id");
  	  		file= xmlhttp.getResponseHeader("Title");
			author= xmlhttp.getResponseHeader("Author");
			security= xmlhttp.getResponseHeader("Security");
			auth= xmlhttp.getResponseHeader("Auth");

			if (security==1) {
				password= xmlhttp.getResponseHeader("Password");
			} else { 
				password="";
  	  		}

  	  		syncFileState();
  	  	
	  	  	if (security==2) {
  		  		secretDialog();
  	  		} else hideDialog();
    	
    		
    	
    	} else {
    		hideDialog();
    		alert("Error saving file. (Type 2)");
    	}
  	 } else {
 	    hideDialog();
   	 	alert("Error saving file. (Type 3)");
  	}
  }
	setStatus("Idle");
}

}




function showDialog(dialog) {
	
	if (dialog=="save") {
		document.getElementById("load").style.display="none";
		document.getElementById("_save").value="Save";
		document.getElementById("_save").disabled=false;
		document.getElementById("savestatus").innerHTML="";
		document.getElementById("secret").style.display="none";
	} else {
		document.getElementById("fileinfo").innerHTML="";
		document.getElementById("passworddiv").style.color="gray";
		document.getElementById("_password2").disabled=true;
		document.getElementById("save").style.display="none";
		document.getElementById("loadstatus").innerHTML="";
		document.getElementById("_load").disabled=true;
		getFileList(180);
	}	
	
	document.getElementById(dialog).style.display="block";	
	document.getElementById("myBody").style.overflow="hidden";
	document.getElementById("gray").style.display="table";

}

function hideDialog(dialog) {
	setStatus("Idle");
	document.getElementById("_password2").value="";
	document.getElementById("gray").style.display="none";
	document.getElementById("myBody").style.overflow="auto";

}

function fullFileList() {


	getFileList(null);
	document.getElementById("liststat").innerHTML="all public Dlogs";
	document.getElementById("showlist").disabled=true;

}


function getFileList(num) {


	var url='http://'+domain+'/dlog/filelist.php';	

	if (num!=null) {
		url+="?length="+num;
	
		document.getElementById("liststat").innerHTML=">3 minute Dlogs";
		document.getElementById("showlist").disabled=false;

	
	
	
	}
	
	xmlhttp=new XMLHttpRequest();
	xmlhttp.onreadystatechange=xmlhttpChange;	
	xmlhttp.open('GET', url, true);
	xmlhttp.setRequestHeader('Content-Type', 'text/xml');
	xmlhttp.send(null);
	
	function xmlhttpChange()
	{
	if (xmlhttp.readyState==4)
 	 {
  	if (xmlhttp.status==200)
  	  {
  	  
  	  	document.getElementById("filelist").innerHTML=xmlhttp.responseText;
  
  	}
	}
	}
  
}





function secretDialog() {

url="http://"+domain+"/dlog/?file="+fileid;
document.getElementById("secret").innerHTML="<p><br>The url to access your hidden document is:"
+"<br><br><input id=url type=text value='"+url+"'>"+
"<br><br>Save this information for future reference.</p><center><input type=button value=OK onClick=\"hideDialog()\"></center>";

document.getElementById("secret").style.display="block";


}


var graph2;


function getFrames() {


	totalTime=0;
	for (i=0;i<data.length;i++) {
		totalTime+=data[i][1];
	}

	var numString="";
	var curText="";
	var totalDelay=0;
	var targetTime=0;
	var currentWords=0;
	frames=new Array();
	timeInc=totalTime/500;
	k=0;
	lastTime=0;
	targetTime=0;
	curTime=0;
	curText="";
	
	for (i=0;i<data.length;i++) {
	
		prevText=curText;
		prevFrame=i;
		curTime+=data[i][1];
		curText=getFrame(data[i],curText);
		
			while (curTime>=targetTime) {
				frames[k]=new Array(prevText,prevFrame,curTime,"@");		

				targetTime+=timeInc;
				
								
				
				k++;
			}
				
		}
	
	
	frames[500]=new Array(masterText,data.length,totalTime,"@");
		
}





function goToTime(time) {
	stopPlayback();
	loadTime(time);
	syncSlider(time);
	
}

function loadTime(time) {
	if (frames==null || frames.length==0) return;
	playbackText=frames[time][0];
	lastFramePlayed=frames[time][1]+1;
	elapsedTime=frames[time][2];
	document.getElementById("page").value=playbackText;
	syncTimer(frames[time][2]/1000);
	
}

function changeFontSize(size) {
	document.getElementById("page").style.fontSize=size+"pt";
}

function changeFontFace(font) {
	document.getElementById("page").style.fontFamily=font;
}



function loadDoc(docID,pw)
{

setStatus("Loading");

// code for Mozilla, etc.
if (window.XMLHttpRequest)
  {
  xmlhttp=new XMLHttpRequest()
  xmlhttp.onreadystatechange=xmlhttpChange;
  xmlhttp.open('GET', 'http://'+domain+'/dlog/data.php?doc='+docID+"&pw="+pw, true);
  xmlhttp.setRequestHeader('Content-Type', 'text/xml');
  xmlhttp.send("");
  }
// code for IE
else if (window.ActiveXObject)
  {
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
    if (xmlhttp)
    {
    xmlhttp.onreadystatechange=xmlhttpChange;
 	xmlhttp.open('GET', 'http://'+domain+'/dlog/data.php?doc='+docID, true);
    xmlhttp.setRequestHeader('Content-Type', 'text/xml');
    xmlhttp.send();
    }
  }
}
function xmlhttpChange()
{
// if xmlhttp shows "loaded"
if (xmlhttp.readyState==4)
  {
  // if "OK"
  if (xmlhttp.status==200)
    {
    
    	error=xmlhttp.getResponseHeader("Error");
		if (error==1) {
			newFile();
			return;
		}
		file= xmlhttp.getResponseHeader("Title");
		fileid= xmlhttp.getResponseHeader("Id");
		author= xmlhttp.getResponseHeader("Author");
		security= xmlhttp.getResponseHeader("Security");
		auth= xmlhttp.getResponseHeader("Auth");
		if (security==1) {
			password= xmlhttp.getResponseHeader("Password");
		} else password="";
		syncFileState();
    	aJSONtext=xmlhttp.responseText;
		loadFile();
		hideDialog();
   }
  
  }
}


function loadFile() {


	if (security==0) {
		document.getElementById("saveButton").disabled=true;
		document.getElementById("recordButton").disabled=true;
	}
	
	data = JSON.parse(aJSONtext);
	masterText=prev=data[data.length-1][2];
	totalTime=data[data.length-1][1];
	docFrame=data[data.length-1];
	data.splice(data.length-1,1);
	getFrames();

	elapsedTime=totalTime;
	setLength(totalTime/1000);
	goToTime(0);
	setStatus("Idle");
	enableControls();
	if (autoplay) startPlayback();
}



function enableControls(flag) {

	if (flag==null) flag=true;
	document.getElementById("playButton").disabled=!flag;
	document.getElementById("rButton").disabled=!flag;
	document.getElementById("ffButton").disabled=!flag;
}


function enableFileControls(flag) {

if (flag==null) flag=true;
	if (security!=0) document.getElementById("saveButton").disabled=!flag;
	document.getElementById("loadButton").disabled=!flag;
	document.getElementById("newButton").disabled=!flag;


}


function initDLog() {

	document.getElementById("page").value="";
	initSlider();
	changeSecurity(0)
}



function syncFileState() {



	
	document.getElementById("_author").value=author;
	document.getElementById("_title").value=file;
	document.getElementById("_security").value=security;
	
	if (fileid!=null && fileid!="") {
		url="http://"+domain+"/dlog/?file="+fileid;
		document.getElementById("title").innerHTML="<a target='_new' href='"+url+"'>"+file+"</a>";
	} else {
		document.getElementById("title").innerHTML=file;
	}
	
	changeSecurity(security);

	
	if (security!=0) {
		document.getElementById("readonly").innerHTML="";
		document.getElementById("recordButton").disabled=false;
	} else {
		document.getElementById("recordButton").disabled=true;
		document.getElementById("readonly").innerHTML="[Read-Only]";
	}

}




function newFile() {

	stopPlayback();
	security=1;	
	fileid="";
	auth="";
	file="untitled";
	author="";
	hasPassword=0;
	syncFileState();	
	data=new Array();
	frames=new Array();
	elapsedTime=totalTime=0;
	enableControls(false);
	setLength(0);
	syncSlider(0);
	document.getElementById("page").value="";
	masterText="";
	lasttime=0;
	
	
	

}



function changeSecurity(type) {


if (type==0) document.getElementById("securityInfo").innerHTML=
	"Document is publicly viewable and cannot be modified.";

if (type==1) {
	document.getElementById("securityInfo").innerHTML=
	"Document is publicly viewable but editing requires a password.";
	document.getElementById("passwordtd").style.color="#000000";
	document.getElementById("_password").disabled=(password!="");
	document.getElementById("_password").value=password;
} else {
	document.getElementById("passwordtd").style.color="#AAAAAA";
	document.getElementById("_password").disabled=true;
	document.getElementById("_password").value="";
}

if (type==2) document.getElementById("securityInfo").innerHTML=
	"Document can only be viewed and edited via a secret url.";


}


lastFile=null;
lastBg="";
selectedFile=null;


function loadSelectedFile() {
	if (selectFile==null) return;
	document.getElementById("loadstatus").innerHTML="<img src=indicator.gif>";
	autoplay=true;
	file=selectedFile;
	pw=document.getElementById("_password2").value;
	loadDoc(selectedFile,pw);
}

function selectFile(tr,id,security,bg) {

if (lastFile!=null) {
	lastFile.style.background=lastBg;
}
lastFile=tr;
lastBg=bg;
tr.style.background="#CCCCFF";

document.getElementById("_load").disabled=false;
selectedFile=id;


if (security==1) {
	document.getElementById("fileinfo").innerHTML="Editing this document requires a password.";
	document.getElementById("passworddiv").style.color="black";
	document.getElementById("_password2").disabled=false;
} else {
	document.getElementById("fileinfo").innerHTML="";
	document.getElementById("passworddiv").style.color="gray";
	document.getElementById("_password2").disabled=true;
}

}