// Mediocre Face
// Ivan Heckman	ivanheckman@hotmail.com
// Copyright (c) 2002
//
// Feel free to link to this, or to take parts or all of it
// (although it's a bit of a mess)
// please keep the Giftshop/LearnHow links in.
//
var isNav, isIE
if (parseInt(navigator.appVersion) >= 4) {
	if (navigator.appName == "Netscape") {
		isNav = true
	} else {
		isIE = true
	}
}

var min_timeout = 10000;
var faceImages = new Array();
var balloonImages = new Array();
var balloonSuffixes = new Array("NE","NW","SE","SW");
var num_balloons = 4;

var URL_BASE	  = "http://www.cs.utoronto.ca/~iheckman/allsnap/";
var LEARN_HOW_URL = URL_BASE + "mediocreface.html";
var GIFTSHOP_URL  = "http://www.cafeshops.com/cp/store.aspx?s=mediocreface";
var FACE_PREFIX = URL_BASE + "images/bored/Bored";
var g_glink = "<a target='_blank' href='" + GIFTSHOP_URL + "'>visit my giftshop</a>";
var	g_plink = "<a target='_blank' href='" + LEARN_HOW_URL + "' >put me on your site</a>";
var right_click_text = "Hi!";


var balloon_PREFIX = "images/balloons/balloon_"
var FACE_suffix  = ".gif";
var average_timeout = 30000;
var face_layer = "faceL";
var faceImgId  = "faceI";
var balloonId   = "balloonI";

var custom_link = "";

var INFINITY = 9999;

//face animation info
var num_faces   = 8;
var sleep_face=6;
var faceTimes = new Array(20,20,20,20,20,20,40,20);
var max_change_time=30000;


//constant size info
var b_width  = 138;
var b_height = 102;
var b_offset = -1;
var f_width  = 17;
var f_height = 17;
var scrollbar_width=19;

var FADE_TOP_OPACITY = 95;
var fade_rate = 30;
var fade_delta = 10;

// other face states
var resting=false;
var talking=false;


//moving state constants
var MS_STARTING = 1;
var MS_STOPPING = 2;
var MS_COASTING = 3;
var MS_STOPPED  = 4;
var move_state  = MS_STOPPED;

//moving variables
var dest_x=0;
var dest_y=0;
var max_dest_x=450;
var max_dest_y=700;
var float_x = 0;
var float_y = 0;

//add more threads to get past ~50ms limit
var num_ani_threads = 2;
var animation_time = 50;

var acceleration = 0;
var start_acceleration	=  0.04;
var stop_acceleration	= -0.04;
var max_move_speed	= 0.5;		//per frame
var current_move_speed  = 0;

var max_think_interval  = 10000;
var P_same_place	= 0.85;
var P_rest = 0.25;
var P_change_z = 0.15;

var min_z	   = 1;
var max_z	   = 5;

var max_rest_time = 10000;

var hideBalloonId = null;
var hideBalloonTime = 2000;

var current_face = 1;

var dragapproved=false;
var z,x,y;

var num_interruptions = 0;
var interruptions = new Array();





//************** MAIN **********************//
	makeface();
	window.onload = init;
//************** MAIN **********************//





// customize functions
function set_P_same_place(p){
	P_same_place = p;
}
function set_P_rest(p){
	P_rest = p;
}
function set_max_rest_time(t){
	max_rest_time = t;
}
function set_balloon_text(str) {
	right_click_text = str;
}
function set_fade_rate(n){
	fade_rate = n;
}
function set_fade_delta(n){
	fade_delta = n;
}


function change_balloon_text(str){
  if(document.all){
  	document.all.balloontext.innerHTML = str;
  }
  else{
  	document.getElementById("balloontext").innerHTML =str;
  }
}

function interrupt(i){
	var obj = interruptions[i];
	if (!talking){
		change_balloon_text(obj.str);
		talk();
		start_hide_balloon(obj.display_time);
	}
	else{ //try later.
		obj.start_time *= 2;
		start_interruption(i);
	}
}

function set_interruption(str,start_time,display_time){
	var obj = new Object;
	obj.str = str;
	obj.start_time = start_time;
	obj.display_time = display_time;

	interruptions[num_interruptions] = obj;
	num_interruptions += 1;
}

function start_interruption(i){
	setTimeout( new Function("interrupt("+ i + ");"),interruptions[i].start_time);
}

//write the html
function makeface(){

	/// main ... adds html for face
	var faceHtml;
	var baloonHtml;
	var put_link;
	var gift_link;
	var talkHtml = "Hi.";
	var glink;
	var plink;
	var isGiftShop=false;
	var loc_str = window.location.href;


	if (loc_str.indexOf(GIFTSHOP_URL) != -1 ){
		talkHtml="<span style='font-size:6pt;'>Welcome to my giftshop!</span>"
		glink = "<span style='color:#cccccc'>visit my giftshop</span>";
		plink = "<a target='_blank' href='" + LEARN_HOW_URL + "' >put me on your site</a>";
		isGiftShop = true;
	}
	else if (loc_str.indexOf(LEARN_HOW_URL) != -1){
		talkHtml="Do it!"
		plink = "<span style='color:#cccccc'>put me on your site</span>";
		glink = "<a target='_blank' href='" + GIFTSHOP_URL + "'>visit my giftshop</a>";
	}
	else if (loc_str.indexOf("allSnap.chm") != -1){
		talkHtml="Hi.";
		glink = "<a target='_blank' href='" + GIFTSHOP_URL + "'>visit my giftshop</a>";
		plink = "<a target='_blank' href='" + LEARN_HOW_URL + "' >put me on your site</a>";
		custom_link = "<a target='_blank' href='http://www.cs.utoronto.ca/~iheckman/allsnap/'>get newest version</a>";

	}
	else{
		glink = "<a target='_blank' href='" + GIFTSHOP_URL + "'>visit my giftshop</a>";
		plink = "<a target='_blank' href='" + LEARN_HOW_URL + "' >put me on your site</a>";
	}



	if(isNav){
		faceHtml=("<img onMouseOut='OnBalloonOut();' onMouseOver='OnBalloonOver()' alt='mediocre face' style='visibility:hidden;Z-INDEX: 2;HEIGHT: 17px; WIDTH: 17px; POSITION: absolute;  TOP: 10px; LEFT: 10px;'  height='17'"
		              + "src='" + FACE_PREFIX + "1.gif' title='right click me' width='17' border='0' id='"
						+ faceImgId + "' />");

	}
	else{
		faceHtml=("<img onMouseOut='OnBalloonOut();' onMouseOver='OnBalloonOver()' alt='mediocre face' style='visibility:hidden;Z-INDEX: 2; FILTER: progid:DXImageTransform.Microsoft.glow(color=#444444,Strength=1); HEIGHT: 17px; WIDTH: 17px; CURSOR: hand; POSITION: absolute;  TOP: 10px; LEFT: 10px;' class='drag'"
						+ "src='" + FACE_PREFIX + "1.gif' title='right click me!' width='17' border='0' id='"
						+ faceImgId + "' />");

	}
	set_balloon_text(
		    talkHtml
			+"<div style='margin-top:1px;margin-bottom:5px;line-height:150%'>"
				+ glink + "<br \>" + plink
			+ "</div>");

	balloonHtml = 	(
	"<div onMouseOut='OnBalloonOut();' onMouseOver='OnBalloonOver()'"
		+"style='border:none;color:black;visibility:hidden;font-size:7pt;font-family:ms sans serif,sans serif;"
			+"position:absolute;top:100px;left:100px;"
			+"width:138px;height:102px;"
			+"text-align:left;"
			+"-moz-opacity:0.95;filter:Alpha(opacity=\"0\");"
			+"padding:0px;"
			+"background-image:url(\"" + URL_BASE
			+"images/balloons/balloon_SW.gif\");"
			+"background-repeat: no-repeat;z-index:100;"
		+"'"
		+ "id='" + balloonId + "'" + ">"

		+"<a style='border:none;text-decoration:none;position:relative;top:16px;left:111px;font-size:10px:line-height:10px;height:10px;width:10px"//top:-58px;"
		+"text-decoration:none;color:black' href='javascript:void(showballoon(false,false))'>"
		+"&nbsp;&nbsp;&nbsp;</a>"
		+ ""
		+"<div id='balloontext' style='width:89px;position:relative;top:7px;left:22px'>"

		+"</div>"
	+"</div>"
	);




	var new_html = faceHtml + balloonHtml

	document.write(new_html);
}



function init(){
	resetMax();
	setRandomPosition();
	//getFace().style.visibility='visible';
	dragInit();
	moveInit();
	changeFaceInit();
	preloadBalloons();
	start_interruptions();
}

function start_interruptions(){
	var i;
	for (i = 0 ; i< num_interruptions ; i++){
		start_interruption(i);
	}
}

function move(){
	if (event.button==1&&dragapproved){
		z.style.pixelLeft=temp1+event.clientX-x
		z.style.pixelTop=temp2+event.clientY-y
		float_x=z.style.pixelLeft;
		float_y=z.style.pixelTop;

		FreezeIt();

		return false;
	}

}
function learnhow(){
	window.location = LEARN_HOW_URL;
}

function giftshop(){
	window.location = GIFTSHOP_URL;
}
function right_click_talk(){
	if (!talking){
		change_balloon_text(right_click_text);
		talk();
	}
}

function talk(){
	positionballoon();
	showballoon(true,false);
}

function drags(){
	if (!document.all){
		return;
	}
	if (event.srcElement.className=="drag"){

		if (event.button==2){
			right_click_talk();
			return;
		}
		else if(talking){
			showballoon(false,true);
		}
		dragapproved=true;
		z=event.srcElement;
		temp1=z.style.pixelLeft;
		temp2=z.style.pixelTop;
		x=event.clientX;
		y=event.clientY;
		document.onmousemove=move;
	}
}

function dragInit(){
	document.onmouseup=new Function("dragapproved=false");
	if (isIE){
		document.onmousedown=drags;
	}
	else{
		document.getElementById(faceImgId).addEventListener("mousedown",beginDrag,false);
	}
}

function moveInit(){
	if (isIE){
		var face= getFace();
		var face_left;
		var face_top;
		face_left =face.offsetLeft;
		face_top  =face.offsetTop;
		face.style.pixelLeft= face_left;
		face.style.pixelTop = face_top;

		float_x = face_left;
		dest_x  = face_left;

		float_y = face_top;
		dest_y  = face_top;

		resetMax();
		think();
		start_animation();
	}
}

function changeFaceInit(){

	preloadFaces();
	cycle_the_face();
}

function getFace() {
		return document.getElementById(faceImgId);
}
function resetMax(){
	var whole_page = document.body;

	max_dest_x=whole_page.offsetWidth - 17;
	max_dest_y=whole_page.offsetHeight - 17;
}

function setRandomPosition(){
	var face = getFace();
	var newX = Math.floor(Math.random() * (max_dest_x));
	var newY = Math.floor(Math.random() * (max_dest_y));

	face.style.left=newX+"px";
	face.style.top=newY+"px";
	
	face.style.visibility = 'visible';

}

function preloadFaces(){
  for(var i=0; i<num_faces; i++){
  	faceImages[i] = new Image();
  	faceImages[i].src=(FACE_PREFIX + i + FACE_suffix);
  }
}

function preloadBalloons(){
	for(var i=0; i<num_faces; i++){
  		balloonImages[i] = new Image(138,102);
  		balloonImages[i].src=(URL_BASE + balloon_PREFIX + balloonSuffixes[i] + '.gif');
  	}
} 

function change_the_face(){
	var new_img;
	var our_face = getFace();

	var face_num

	do{
		face_num = Math.floor(Math.random() * (num_faces));
	}while (( (face_num == sleep_face) && talking));

	current_face = face_num;
	our_face.src = faceImages[face_num].src;

	if (face_num == sleep_face){
		was_sleeping = true;
		StartStopping();
	}
	else{
		if (was_sleeping){
			StartMoving();
		}
		was_sleeping = false;
	}
	return face_num;
}

var was_sleeping = false;
function cycle_the_face(){
	var face_num = change_the_face();
	setTimeout(cycle_the_face,faceTimes[face_num]*1000);
}

function start_animation(){

	for(var i=0;i<num_ani_threads;i++){
		setTimeout(moveIt,animation_time);
	}
}

function moveIt(){
	var obj=getFace();
	var dx = dest_x - float_x;
	var dy = dest_y - float_y;


	var magnitude = Math.sqrt(dx*dx + dy*dy);
	var can_get_closer = (magnitude + stop_acceleration > 0);

	if (!dragapproved && can_get_closer){

		//update_debugform()

		if ( isMoving() &&
		     stopping_distance
		     (current_move_speed,
		      stop_acceleration) >= magnitude ) {
			StartStopping();
		}

		var next_move_speed = current_move_speed + acceleration;

		if (next_move_speed<0){
			FreezeIt();
		}
		else if (next_move_speed > max_move_speed){
			StartCoasting();
		}
		else{
			current_move_speed += acceleration;
		}

		if (magnitude > current_move_speed){
			var mx = (dx/magnitude)* current_move_speed;
			var my = (dy/magnitude)* current_move_speed;

			float_x += mx;
			float_y += my;
		}
		else{
			float_x = dest_x;
			float_y = dest_y;
		}

		obj.style.pixelLeft = Math.round(float_x);
		obj.style.pixelTop  = Math.round(float_y);

	}

	setTimeout(moveIt,animation_time * num_ani_threads);
}


function think(){
		//face animation now independant of other stuff
	if (!(resting || talking || current_face == sleep_face)
		&& Math.random() > P_same_place){
		change_dest();
	}

	if (!(resting || talking)  && Math.random() < P_rest){
		StartStopping();
		have_a_rest();
	}
	if (!talking && Math.random() < P_change_z){
		change_z();
	}

	var next_think = Math.floor(Math.random() * max_think_interval);


	setTimeout(think,max_think_interval);
}
function change_z(){
	var range = max_z - min_z;
	var new_z = min_z + Math.floor( Math.random() * (range +1));
	var obj = getFace();
	obj.style.zIndex = new_z;
}
function get_to_work(){
	resting=false;
	StartMoving();
	//debugform.resting.value="FALSE";
}

function have_a_rest(){
	if (!resting){
		resting=true;
		//debugform.resting.value="TRUE";
		var wake_time = Math.floor(Math.random() * (max_rest_time));
		setTimeout(get_to_work,wake_time);
	}
}


function isMoving(){
	return (move_state != MS_STOPPED);
}
function isStopping(){
	return (move_state == MS_STOPPING);
}
function isStarting(){
	return (move_state == MS_STARTING);
}
function StartCoasting(){
	move_state = MS_COASTING;
	acceleration = 0;
}

function FreezeIt(){
	accleration = 0;
	move_state  = MS_STOPPED;
	dest_x = float_x;
	dest_y = float_y;
	current_move_speed = 0;
}
function StartStopping(){
	move_state = MS_STOPPING;
	acceleration = stop_acceleration;
}

function StartMoving(){
	move_state = MS_STARTING;
	acceleration =start_acceleration;
}


function change_dest(){
	var rnd_x= Math.random();
	var rnd_y= Math.random();
	dest_x=Math.floor( (rnd_x) * (max_dest_x));
	dest_y=Math.floor( (rnd_y) * (max_dest_y));
	StartMoving();
}

function stopping_distance(Vo,a){
	var t = -1 * Vo / a;
	return Vo * t + (1/2) * a * (t * t);
}

function positionballoon(){
	var f = getFace();
	var x = findPosX(f);
	var y = findPosY(f);
	var win_width  = getWindowWidth();
	var win_height = getWindowHeight();
	var b = document.getElementById(balloonId);
	var suffix = "";
	var bIndex; // 0 = "NE", 1 = "NW", 2 = "SE", 3 = "SW"
	
	if ( (y - b_offset - b_height) <= 0){
		b.style.top = (y + f_height + b_offset) + "px";
		bIndex = 0;
	}
	else{
		b.style.top = (y - (b_height + b_offset) ) + "px";
		bIndex = 2;

	}

	if ( (x + (f_width + b_offset + b_width )) >= (win_width - scrollbar_width)){
		b.style.left = (x - (b_width + b_offset)) + "px";
			}
	else{b.style.left = (x + f_width + b_offset) + "px";
		bIndex++;

	}
	if ( b.style.backgroundImage != "url("+ balloonImages[bIndex] + ")"){
	
		b.style.backgroundImage = "url("+ balloonImages[bIndex].src + ")";
	}
}

function showballoon(visible,isQuick){

	((isNav)?window:document).oncontextmenu = (!visible)?null:new Function("return false;");

	var b = document.getElementById(balloonId);

	//g_leftballoon = false;

	if (visible){
		b.style.visibility = 'visible';

		if (!isQuick){
			idFade(b,FADE_TOP_OPACITY,fade_rate,fade_delta,null);
		}else{
			if (!isNav){
				b.filters.alpha.opacity = TOP_OPACITY;
			}
		}
		talking=true;
		getFace().src=FACE_PREFIX + "Talking" + FACE_suffix;
		setTimeout(change_the_face,1000);
				//OnBalloonOut();
		FreezeIt();


	}
	else{
		if (!isQuick){
			idFade(b,0,fade_rate,fade_delta,new Function("document.getElementById(balloonId).style.visibility = 'hidden';"));
		}
		else{
			if (!isNav){
				b.filters.alpha.opacity = 0;
			}
			b.style.visibility = 'hidden';
		}

		OnBalloonOver();
		talking=false;
		StartMoving();

	}
}

//functions to hide balloon after a while
function OnBalloonOut(){
//	g_leftballoon = true;
	if (talking){
		start_hide_balloon(hideBalloonTime);
	}
}

function start_hide_balloon(t){
	if (hideBalloonId!=null){
		clearTimeout(hideBalloonId);
	}
	hideBalloonId = setTimeout(new Function("showballoon(false,false)"),t);
}

function OnBalloonOver(){
	//g_leftballoon=false;
	if (talking && hideBalloonId != null){
		clearTimeout(hideBalloonId);
		hideBalloonId = null;
	}
}

function getWindowWidth(){
	if(document.innerWidth){
		return document.innerWidth;
	}
	else if (document.body.offsetWidth){
		return document.body.offsetWidth;
	}
}
function getWindowHeight(){
		if(document.innerHeight){
			return document.innerHeight;
		}
		else if (document.body.offsetHeight){
			return document.body.offsetHeight;
		}
}



//from http://www.xs4all.nl/~ppk/js/index.html?version5.html
function findPosX(obj)
{
	var curleft = 0;
	if (document.getElementById || document.all)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (document.layers)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (document.getElementById || document.all)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (document.layers)
		curtop += obj.y;
	return curtop;
}
//

idFadeObjects = new Object();
idFadeTimers = new Object();

//fade script from http://wai.devmag.net/tricks/js/javascript_4.htm?&template=/template/wai.tpl
function idFade(object, destOp, rate, delta, onFinish){
	if (!document.all){
		if(onFinish){
			onFinish();
		}
		return;
	}
	if (object != "[object]"){

		setTimeout("idFade("+object+","+destOp+","+rate+","+delta+","+onFinish+")",0);
		return;
	}

	clearTimeout(idFadeTimers[object.sourceIndex]);

	diff = destOp-object.filters.alpha.opacity;
	direction = 1;
	if (object.filters.alpha.opacity > destOp){
		direction = -1;
	}
	delta=Math.min(direction*diff,delta);
	object.filters.alpha.opacity+=direction*delta;

	if (object.filters.alpha.opacity != destOp){
		idFadeObjects[object.sourceIndex]=object;

		idFadeTimers[object.sourceIndex]=
		setTimeout("idFade(idFadeObjects["+object.sourceIndex+"],"+destOp+","+rate+","+delta+","+onFinish+")",rate);
	}
	else{
		//
		if (onFinish!=null){
			onFinish();
		}
	}

}
//fade script from http://wai.devmag.net/tricks/js/javascript_4.htm?&template=/template/wai.tpl


//=============== MOZILLA DRAG ================//
	function doDrag(e) {
		// Calculates the difference from the last stored position to
		// the current position.
		//
			if ( dragapproved){
				var difX=e.clientX-window.lastX;
				var difY=e.clientY-window.lastY;

			// Retrieves the X and Y position of editcanvas.
			//
				var newX = parseInt(document.getElementById(faceImgId).style.left)+difX;
				var newY = parseInt(document.getElementById(faceImgId).style.top)+difY;

			// Sets the new position for the editcanvas div element.

				document.getElementById(faceImgId).style.left=newX+"px";
				document.getElementById(faceImgId).style.top=newY+"px";

			// Stores the current mouse position as last position.
			//
				window.lastX=e.clientX;
				window.lastY=e.clientY;
				return false;
	        }
	}

	//----------------------------------------------------------------------------
	// When drag begins, this function is called.
	//
	function beginDrag(e) {
			document.oncontextmenu = new Function("return false;");
			if (e.button==2){
						endDrag();
						right_click_talk();
			}
			else if(talking){
				showballoon(false,true);
			}
			else{
			// Stores the current mouse position
				window.lastX=e.clientX;
				window.lastY=e.clientY;

				dragapproved=true;
			// Registering doDrag event handler to receive onmousemove events.
				window.onmousemove=doDrag;

			// Registering endDrag event handler to receive onmouseup events.
			//	window.onmouseup=endDrag;
			}
	        document.oncontextmenu = null;
	        return false;
	}

	//----------------------------------------------------------------------------
	// Called when the mouse button is released.
	// This event handler was registered in beginDrag function.
	//
	function endDrag(e){// Release doDrag event handler assignment.
	        window.onmousemove=null;
	        return false;

	}
//END Mozilla drag


//The code Get_Cookie(), Set_Cookie() and Delete_Cookie() is based on the public domain cookie code produced by Bill Dortch.

function Get_Cookie(name) {
    var start = document.cookie.indexOf(name+"=");
    var len = start+name.length+1;
    if ((!start) && (name != document.cookie.substring(0,name.length))) return null;
    if (start == -1) return null;
    var end = document.cookie.indexOf(";",len);
    if (end == -1) end = document.cookie.length;
    return unescape(document.cookie.substring(len,end));
}

function Set_Cookie(name,value,expires,path,domain,secure) {
    document.cookie = name + "=" +escape(value) +
        ( (expires) ? ";expires=" + expires.toGMTString() : "") +
        ( (path) ? ";path=" + path : "") +
        ( (domain) ? ";domain=" + domain : "") +
        ( (secure) ? ";secure" : "");
}

function Delete_Cookie(name,path,domain) {
    if (Get_Cookie(name)) document.cookie = name + "=" +
        ( (path) ? ";path=" + path : "") +
        ( (domain) ? ";domain=" + domain : "") +
        ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}


