/****************************************************/
/* Author: Yuri Shanoilo							*/
/*													*/
/* Start examination from functions					*/
/* handleMouseOver and handleMouseOut				*/
/****************************************************/

var nm=6;
var sstr="/images/image";
var eos=".jpg";

imgs=new Array(nm*2);
for (i=1;i<=nm*2;i++) { imgs[i] = new Image(); imgs[i].src=sstr+i+eos;}

//=====================================Menu Function=============================================
var TimeoutLength = 95;  		// Time after which menu will be redrawn (in miliseconds)
var behaviourType = 'delay';	//Behavour type (immediate, delay, windows)


var menuTimeoutPointer;   		// Pointer to menu timeout object
var oldOvered = null;			//Menu item which was overed
var newOvered = null;			//Menu item which may have class over - so on which is user mouse
var windowsOveredItem = null;
var commonPoint = false;		//Common point for new and old overed menu items
var lastElementIsMenu = true;

var reMenu = new RegExp("(^menu$)|(^menu1$)|(^menu3$)");
var reClik = new RegExp("(^| )" + "clik" + "($| )");


//This function add some test data to title (convenient for testing)
function addTitle(text)
{
 	if (document.title.length > 55) {
 		document.title = '';
 	}                                	
	document.title += ' ' + text + ' ';
}

function addText(text)
{
	document.all.test.innerText += ' ' + text + ' ';
}


/* handling multiple styles applied to an element */
function addStyle(obj, class_name) {
    var cn = obj.className;
    var re = new RegExp("(^| )" + class_name + "($| )");
    var re1 = new RegExp("(^| )"  + "*cust" + class_name + "($| )");
    var re2 = new RegExp("cust");
    if (cn.search(re) != -1) return false;
    if (cn.search(re1) != -1) return false;
    if ((cn.search(re2) != -1) && ((class_name == "sub") || (class_name == "sub over"))) {
		cn = cn.replace(re2, "cust" + class_name);
	} else {
	    if (cn != "" && cn.charAt(cn.length - 1) != " ") cn += " ";
	    cn += class_name;
	}
    obj.className = cn;
}

function removeStyle(obj, class_name) {
    if (!obj) return;
    var re = new RegExp(" " + class_name + " ");
    var re1 = new RegExp("(^" + class_name + " )|( " + class_name + "$)|(^"
                           + class_name + "$)");
    var re2 = new RegExp("cust" + class_name + "($| )");

    var cn = obj.className;
    cn = cn.replace(re, " ");
    cn = cn.replace(re1, "");
    cn = cn.replace(re2, "cust");
    obj.className = cn;
}


//Return parent Node. Works in all modern browsers
function getParent(obj) {
	//Checks if this is IE (because IE 5 do not support parentNode)
	if (obj.parentElement) {
		return obj.parentElement;
	} else {
		return obj.parentNode;
	}
}

//Getting event source element. Works in all modern browsers
function getSourceElement(e) {
	//Checks if this is IE (because IE works with events in different way)
	if (e) {
		return e.target;
	} else {
		return event.srcElement;
	}
}

/*check if obj is menu item or its contents (oblect if true, null if false) */
/*Should work much more faster in case if object is not menu item - there should be some way to do that*/
/*Should return <li> element and only it*/
function isMenuItem(obj) {
	if (!obj) {
		return false;
	}
	
	//Is needed for Safari - because in Safari text in <a> is also mouse overed but it does not have
	//tagName - therefore this function do not work in some cases
	if (!obj.tagName) {
		obj = getParent(obj);
	}
	
    //Finds parent li and returns it
    var element = false;
    while (obj && (obj != document) && ((obj.tagName.toLowerCase() != "ul") || ((obj.className.toLowerCase() != "menu") && (obj.className.toLowerCase() != "menu1") && (obj.className.toLowerCase() != "menu3")))) {
        if ((obj.tagName.toLowerCase() == "li") && (!element)) {
        	element = obj;
		}
        obj = getParent(obj);
    }
    if (element && obj.className && ((obj.className.toLowerCase() == "menu") || (obj.className.toLowerCase() == "menu1") || (obj.className.toLowerCase() == "menu3"))) return element;
    
    return false;
}


//Returns path of the <li> elements starting from oldOvered and finishing with
//topmost <li> ancestor of it in menu
function getOldPath() {
	if (!oldOvered) return null;
	
	pathArray = new Array();
	pathArray[0] = oldOvered;
	var obj = getParent(oldOvered);
	
    while (obj && (obj != document) && (obj.className.search(reMenu) == -1)) {
        if (obj.tagName.toLowerCase() == "li") {
        	pathArray[pathArray.length] = obj;
        }
        obj = getParent(obj);
    }
	
	return pathArray;
}

//Finds common point - point of intersection between old and new branches
function findCommonPoint(oldPath) {
	//If there is no old path then there is no common point (if old overed item is not menu element)
	if (!oldPath) {
		commonPoint = false;
		return true;
	}
	
	var obj = newOvered;
	//Moving up in new branch and checking if oldPath contain some element in it
	//The first matching element is common point
    while (obj && (obj != document) && (obj.className.search(reMenu) == -1)) {
        if (obj.tagName.toLowerCase() == "li") {
        	for (var i=0; i < oldPath.length; i++) {
				if (oldPath[i] == obj) {
					commonPoint = obj;
					return true;
				}
			}
        }
        obj = getParent(obj);
    }
    
	//If there is no same elements in new and old branches then there is no common point
	commonPoint = false;
	return true;
}


function removeStyles(obj) {
	removeStyle(obj,"sub");
	removeStyle(obj,"over");
	
}

function closeOldBranch() {
	var obj = oldOvered;
	
    while (obj && (obj != commonPoint) && (obj != document) && (obj.className.search(reMenu) == -1)) {
        if (obj.tagName.toLowerCase() == "li") {
        	removeStyles(obj);
        }
        obj = getParent(obj);
    }
	
}


function openNewBranch() {
	var obj = newOvered;
	
    while (obj && (obj != commonPoint) && (obj != document) && (obj.className.search(reMenu) == -1)) {
        if (obj.tagName.toLowerCase() == "li") {
        	addStyle(obj,"sub");
        	if (obj == newOvered) {
        		addStyle(obj,"over");
        	}
        }
        obj = getParent(obj);
    }
}

function redrawMenu() {
	var path = new Array();
	
	path = getOldPath();
	
	findCommonPoint(path);
	
	closeOldBranch();
	
	openNewBranch();
	
	oldOvered = newOvered;
	if (!newOvered) {
		oldOvered = null;
	}
}


function handleMouseOver(e) {
    var el = getSourceElement(e);
    change(el,1);

    //Getting overed <li> element (if li was overed)
    var menuitem = isMenuItem(el);

    if (menuitem) {
    	lastElementIsMenu = true;
    	newOvered = menuitem;

    	//Clearing old call of menu redraw because mouse was moved
    	clearTimeout(menuTimeoutPointer);


	    if (behaviourType == 'immediate') {
	    	redrawMenu();
	    }
	    //Checking if this is not the same element which was already overed
	    else if (behaviourType == 'delay' && menuitem != oldOvered) {
	    	//Calling menu redraw - if mouse will not be moved again
			menuTimeoutPointer = setTimeout('redrawMenu()', TimeoutLength);
	    }
	    else if (behaviourType == 'windows') {
	    	if (!windowsOveredItem) {
	    		windowsOveredItem = menuitem;
	    	}
	    	
	    	if (windowsOveredItem != menuitem) {
	    		removeStyle(windowsOveredItem,"over");
	    		windowsOveredItem = menuitem;
	    		addStyle(windowsOveredItem,"over");
	    	}
	    	//Calling menu redraw - if mouse will not be moved again
			menuTimeoutPointer = setTimeout('redrawMenu()', TimeoutLength);
	    }
    }
}


function handleMouseOut(e) {
	el = getSourceElement(e);
	change(el,-1);

	//Checking if mouse is moved out from menu - otherwise this code was already called
	//and there is no need to call it again
	if (lastElementIsMenu) {
		//New overed element is not menu item
		newOvered = null;
		
		//Clearing old call of menu redraw because mouse was moved
		clearTimeout(menuTimeoutPointer);
		
		//Calling menu redraw - if mouse will not be moved again
		menuTimeoutPointer = setTimeout('redrawMenu()', TimeoutLength);
	}
	lastElementIsMenu = false;
}


function handleClick(e) {
	//Getting cliked element
    var el = getSourceElement(e);
    var menuitem = isMenuItem(el);

    if (menuitem) {
    	if (menuitem.className.search(reClik) == -1) {
    		addStyle(menuitem,"clik");
    	} else {
    		removeStyle(menuitem,"clik");
    	}
    }
    
	//If was clicked menu item but not <a>
    if (menuitem && el.tagName.toLowerCase() != "a") {
    	
    	//Getting first <a> inside clicked element
		neededA = menuitem.getElementsByTagName("a");
		if ( neededA.length != 0 ) {
			var neededLocation = false;
			var neededLink = false;
			if (neededA[0].getAttribute('href',2)) {
				neededLink = neededA[0].getAttribute('href',2);
			}
			if (neededA[0].getAttribute('target',2)) {
				neededLocation = neededA[0].getAttribute('target',2);
			}
			
			//If <a> has attribute target="_blank" then opening link in new window
			if (neededLocation && neededLocation == "_blank")
			{
				window.open(neededLink,"","");
			} else if (neededLink) {
				location.assign(neededLink);
			}
		}
	}
}


//Is not really needed for  menu
function handleLoad() {
	//Adding validator to forms
	var forms = document.getElementsByTagName("FORM");
    for (var i = 0; i < forms.length; i++) {
        if (forms[i].className.indexOf("contact") != -1) {
			doShow(forms[i]);
        }
    }
}

//Function which helps to hide errors if needed
function errorTrap() {
    return true;
}

function change(e,m) {
	if (e.tagName!="IMG") return true;
	var str=e.src;
	var i=str.indexOf(sstr);
	if (i==-1) return true;
	var n=parseInt(str.substring(str.length-4,i+sstr.length))+m;

	e.src=imgs[n].src;
}

//Handlers initiations
document.onmouseover = handleMouseOver;
document.onmouseout = handleMouseOut;
document.onclick = handleClick;
window.onload = handleLoad;
//window.onerror=errorTrap;
