POPUP_DELAY = 300;   // milliseconds after mouseover for popup menu
BASE_ZINDEX = 500;

mX = 0;
mY = 0;

mXOffset = 30;
mYOffset = 15;

old_parent_zindex = 0;	// global

M_LEVELS = 10;
SUBMENUS = [];

curcat_arr = [];	// global array containing current cat tree as strings

return_elem = null;

ROOTLINK = 'rootLink';   // in case we don't get passed the right link

function ab_register_return_elem (formelem) {
  // we are starting a menu cascade; each submenu is static but will call ab_select on click
  // since we only support one active instance of cascading menus per page, we only need to
  // register once on initiating the cascade so ab_select knows who to return the selected cat to

  if (formelem && ! return_elem) {  // don't re-register if already set, could cause error
	  return_elem = formelem;
  }

}

function ab_select (catcodestr, catname) {
 // user has selected a category from a pop-up cascade in a non-browsing context
 // generally, we are popped up from a form element, we want to return the catcode and name
 // to that form element
    
// if option elem, we can return value + text

	return_elem.value = catcodestr;
	curcat_arr.push(catname);
	return_elem.text = curcat_arr.join(':');

// TODO if we have a window, we open the link in that window

	ab_remove_all();

 // categories with content will be available for browsing, and can click directly to
 // good browsable URLs /cat/subcat/subcat/subcat/  which a handler can deal with


}

function ab_init_menus () {

	for (j=1; j<M_LEVELS+1; j++) {
 		mid = 'menu_level_' + String(j);

        	SUBMENUS[j] = document.getElementById(mid);
	}

}

function ab_have_session () {
        var allcookies = document.cookie;

        var pos = allcookies.indexOf("PHPSESSID=");

        if (pos == -1) {
                return false;
        } else {
                return true;
        }
}


function ab_set_timer_cascade(elem,evnt,catcode,is_top_level, m_return_elem,new_win_name) {
	
	var timer;

	// COULD START LOADING DATA NOW if we want - make behavior really slick!

	mX = evnt.clientX;
	mY = evnt.clientY;

	if (m_return_elem) {
		ab_register_return_elem(m_return_elem);
	}	

// TODO: register new win name, and when we finish we open link in that window
	// the event is the mouseover the menu element
	if (is_top_level) {
		timer = window.setTimeout(function() { 
		 	ab_top_cascade(elem, catcode); 
		}, POPUP_DELAY);
	} else {
		timer = window.setTimeout(function() {
			ab_cascade(elem, catcode);
		}, POPUP_DELAY);
	}	

	// code supporting multiple browsers from O'Reilly JS book rev 5 p 420
	if (elem.addEventListener) { elem.addEventListener("mouseout", ab_cancel_timer, false); }
	else if (elem.attachEvent) { elem.attachEvent("onmouseout", ab_cancel_timer); }
	else { elem.onmouseout = ab_cancel_timer; }

	function ab_cancel_timer() {
		window.clearTimeout(timer);
		if (elem.removeEventListener) {
			elem.removeEventListener("mouseout",ab_cancel_timer, false);
		} else if (elem.detachEvent) { elem.detachEvent("onmouseout",ab_cancel_timer); }
		else { elem.onmouseout = null; }

		// turn progress cursor off
		// cursor = pointer
		// thislink not defined
		elem.setAttribute("style","cursor: pointer;");
	}			
}


function ab_remove_all () {
        for (x = 1; x<=M_LEVELS; x++) {
              if (SUBMENUS[x]) {
                   SUBMENUS[x].style.display = 'none';
              }
        }
}

function ab_remove_panel(mlink) {
        var mpanel = mlink.parentNode.parentNode; 
        if (mpanel) {
                 mlevelstr = mpanel.getAttribute("level");
        	if (mlevelstr){
                	mlevelnum = parseInt(mlevelstr);
	        } else {
        	        mlevelnum = 1;
		}
		for (x = mlevelnum; x<M_LEVELS; x++) {
			if (SUBMENUS[x]) {
				SUBMENUS[x].style.display = 'none';
			}
		}

		if (mlevelnum > 1) {
			SUBMENUS[mlevelnum - 1].style.background = '#fff';
		}

		mpanel.style.display = 'none';	// should already be done
        }
}

function ab_top_cascade(thislink, catcode, m_return_elem) {
	//ab_remove_all();
	// TODO: register thislink or formelem for return
	ab_cascade(thislink, catcode, m_return_elem);

}

function ab_cascade(thislink, catcode, m_return_elem) {

	mparent = thislink.parentNode;
	if (! mparent) {	// sometimes we don't get a good thislink
		newlink = document.getElementById(ROOTLINK);
		if (newlink) {
			thislink = newlink;
			mparent = thislink.parentNode;
		} else {
			mparent = thislink;
		}
	}

	if (m_return_elem) {  // usually only defined on first call
		ab_register_return_elem(m_return_elem); 	
	}

	mlevelstr = mparent.getAttribute("level") || 0;
	if (mlevelstr){
		mlevelnum = parseInt(mlevelstr) + 1;

		// Darken our immediate parent
		SUBMENUS[mlevelnum - 1].style.background = '#aaa';
	} else {
		mlevelnum = 1;
	}

	// Brighten us
	SUBMENUS[mlevelnum].style.background = '#fff';
	
	// Hide any menus lower than our current level
	for (x = mlevelnum+1; x<=M_LEVELS; x++) {
		if (SUBMENUS[x]) {
			SUBMENUS[x].style.display = 'none';
		}
	}
	curcat_arr[mlevelnum - 1] = thislink.getAttribute("catname");
	curcat_arr.length = mlevelnum;

	mzindex = BASE_ZINDEX + mlevelnum *10;

	mpop = SUBMENUS[mlevelnum];
	
	mpop.style.zIndex = mzindex;
	// for the top level, we use mouse position
	if (mlevelnum <=1 ) { 

		// Could move into position based on mparent
		// here we use the coords of the mouse event if we have them 
		if (! mX && ! mY) {
			mX = parseInt(thislink.offsetLeft) + mXOffset;
			mY = parseInt(thislink.offsetTop) + mYOffset;
		} else {
		// we are using mouse coords, may have to offset for window scroll
			mY = mY + getScrollY();
		}

		mParentX = mpop.parentNode.style.left;
		mParentY = mpop.parentNode.style.top;
	
		mXOff = (mX - mParentX);
		mYOff = (mY - mParentY);
	} else {

// we use a fixed offset from the previous submenu
		mX = mXOffset + parseInt(SUBMENUS[mlevelnum - 1].style.left);
		mY = mYOffset + parseInt(SUBMENUS[mlevelnum - 1].style.top);
	}


	mStrX = String(mX) + 'px';
        mStrY = String(mY) + 'px';

	mpop.style.display = 'none';	// disappear while we fill and move it
	mpop.innerHTML = '';
        fill_elem_from_catcode (mpop, catcode);

//alert ("left was " + mpop.style.left + " now setting to " + mStrX);

	// in case element is scrolled

	mpop.style.left = mStrX;  // was mXOff
	mpop.style.top = mStrY;  // was mYOff

	// empty mX and mY
	mX = 0;
	mY = 0;

	mpop.style.display = 'block';
}


function fill_elem_from_catcode ( fill_elem, catcode ) {
	// use subdir hierarchy for dmoz cats
	// for smaller lists of catcodes we just use compressed catcode for filename
       var dataurl = "/inc/abracats/" + catcode + "/index.html";

//alert("Data url is " + dataurl);
	fill_elem.parentNode.setAttribute("style","cursor: wait;");

        var myAj = new Ajax.Updater(
                fill_elem,
                dataurl,
                {
                        method: 'get',
			onComplete: function(transport) {
				fill_elem.parentNode.setAttribute("style","cursor: pointer;");
			}
                }
        );

		// TODO: callback to turn progress off after data loaded

		// TODO TODO  - also should only set display=block AFTER correct data loads

		// turn progress cursor off
		// cursor = pointer
		//thislink.setAttribute("style","cursor: pointer;");

}

function ab_hide_popwin (elemname) {
        $(elemname).style.visibility = 'hidden';
	
}

function ab_show_popwin(elemname, content_url ) {

        $(elemname).style.visibility = 'visible';

        var myAj = new Ajax.Updater(
                $(elemname),
                content_url,
                {
                        method: 'get'
                }
        );
}



function showLogin () {
	
	var my_login_text = document.createTextNode("Username: ");
	var my_login_elem = document.getElementById("login_label");
	var my_button_elem = document.getElementById("login_button");
	my_login_elem.appendChild(my_login_text);

	var my_inp_login = document.createElement("input");
	my_inp_login.name = "login";
	my_inp_login.type = "text";
	my_inp_login_size = "20";

	my_login_elem.appendChild(my_inp_login);

	var my_login_br = document.getElementById("login_br");
	var my_br = document.createElement("br");
	if (my_login_br) {
		my_login_br.appendChild(my_br);
	}

	var my_passwd_text = document.createTextNode("Password: ");
	var my_passwd_elem = document.getElementById("passwd_label");
	my_passwd_elem.appendChild(my_passwd_text);

	//var my_login_form = document.getElementById("login_form");		

	//my_login_form.appendChild(my_inp_login);

	var my_inp_passwd = document.createElement("input");
	my_inp_passwd.name = "password";
	my_inp_passwd.type = "PASSWORD";
	my_inp_passwd_size = "20";

	my_passwd_elem.appendChild(my_inp_passwd);

	
	var my_submit = document.createElement("input");
	my_submit.value="Login";
	my_submit.name="Submit";
	my_submit.type="submit";

	my_button_elem.appendChild(my_submit);

	// add a 'Login' button
	var my_login_text = document.getElementById("login_text");
	my_login_text.textContent = "";

	var my_reg_text = document.getElementById("reg_text");
	my_reg_text.textContent = "";

	var my_login_form = document.getElementById("login_form");		

	if (! my_login_form) {
		alert("Can't get element by id for login_form");
	}


}

function hideAddForm () {
        $('placeAddForm').style.display = 'none';
}

function showAddForm(formurl) {

        if ($('placeAddForm').style.display == 'none') {
                $('placeAddForm').style.display = '';
        } else {
                var myAj = new Ajax.Updater(
                        $('placeAddForm'),
                        formurl,
                        {
                                method: 'get'
                        }
                );
        }
}

// from www.daniweb.com/techtalkforums/thread45103.html
function addBookmark(title, url) {
        if (window.sidebar) { // firefox
              window.sidebar.addPanel(title, url,"");
        } else if( window.external ) { //MSIE
                window.external.AddFavorite( url, title);
        } else {
               alert("Sorry, your browser doesn't support this");
        }
}

// written according to info from O'Reilly's Javascript Guide 5th ed, p 914
function getScrollY() {
	if (window.pageYOffset) { // all except IE 
		return(window.pageYOffset);
	} else if (document.documentElement.scrollTop) { // one version of IE
		return(document.documentElement.scrollTop);
	} else if (document.body.scrollTop) {  // another version of IE
		return(document.body.scrollTop);
	} else {
		return(0);	// at least defined
	}
}

function show_section(mname) {

   melem = document.getElementById(mname);

   melem.style.display = "block";

}

function hide_section(mname) {

   melem = document.getElementById(mname);

   melem.style.display = "none";

}


