// $Id: common.js,v 1.25 2006/05/02 17:28:39 tvroom Exp $
faq={
	triggerElements:'*', 	// elements to trigger the effect
	parentElementId:null,	// ID of the parent element (keep null if none)
	uniqueCollapse:false,	// is set to true only one element can be open at a time

	// CSS class names
	trigger:'trigger',
	triggeropen:'expanded',
	hideClass:'hide',
	showClass:'show',

	// pictures and text alternatives
	closedPicH4:'../../images/treenode_white_16x16_collapsed.gif',
	closedAltH4:'Expand FAQ Section',
	openPicH4:'../../images/treenode_white_16x16_expanded.gif',
	openAltH4:'Collapse FAQ Section',
	closedPicH5:'../../images/treenode_black_16x16_collapsed.gif',
	closedAltH5:'Expand FAQ Entry',
	openPicH5:'../../images/treenode_black_16x16_expanded.gif',
	openAltH5:'Collapse FAQ Entry',
	/* Doesn't work with Safari
		hoverClass:'hover',
	*/

	init:function(e){
		var temp;
		if(!document.getElementById || !document.createTextNode){return;}
		if(!faq.parentElementId){
			temp=document.getElementsByTagName(faq.triggerElements);
		} else if(document.getElementById(faq.parentElementId)){
			temp=document.getElementById(faq.parentElementId).getElementsByTagName(faq.triggerElements);
		}else{
			return;
		}
		faq.tempLink=document.createElement('a');
		faq.tempLink.setAttribute('href','#');
		faq.tempLink.appendChild(document.createElement('img'));
		for(var i=0;i<temp.length;i++){
			if(faq.cssjs('check',temp[i],faq.trigger) || faq.cssjs('check',temp[i],faq.triggeropen)){
				faq.makeTrigger(temp[i],e);
			}
		}
	},
	makeTrigger:function(o,e){
		var tl=faq.tempLink.cloneNode(true);
		var tn=o.tagName;
		var tohide=o.nextSibling;
		while(tohide.nodeType!=1)
		{
			tohide=tohide.nextSibling;
		}
		o.tohide=tohide;
		if(!faq.cssjs('check',o,faq.triggeropen)){
			faq.cssjs('add',tohide,faq.hideClass);
			tl.getElementsByTagName('img')[0].setAttribute('src', (tn=='H4')?faq.closedPicH4:faq.closedPicH5);
			tl.getElementsByTagName('img')[0].setAttribute('alt', (tn=='H4')?faq.closedAltH4:faq.closedAltH5);
			o.setAttribute('title', (tn=='H4')?faq.closedAltH4:faq.closedAltH5);
		}else{
			faq.cssjs('add',tohide,faq.showClass);
			tl.getElementsByTagName('img')[0].setAttribute('src',(tn=='H4')?faq.openPicH4:faq.openPicH5);
			tl.getElementsByTagName('img')[0].setAttribute('alt',(tn=='H4')?faq.openAltH4:openAltH5);
			o.setAttribute('title', (tn=='H4')?faq.openAltH4:openAltH5);
			faq.currentOpen=o;
		}
		faq.addEvent(o,'click',faq.addCollapse,false);
		/* Doesn't work with Safari
		faq.addEvent(o,'mouseover',faq.hover,false);
		faq.addEvent(o,'mouseout',faq.hover,false);
		*/
		o.insertBefore(tl,o.firstChild);
		faq.addEvent(tl,'click',faq.addCollapse,false);
		// Safari hacks 
		tl.onclick=function(){return false;}
		o.onclick=function(){return false;}
	},
	/* Doesn't work with Safari
	hover:function(e){
		var o=faq.getTarget(e);
		var action=faq.cssjs('check',o,faq.hoverClass)?'remove':'add';
		faq.cssjs(action,o,faq.hoverClass)
	},
	*/
	addCollapse:function(e){
		var action,pic;
		var o=faq.getTarget(e);
		var tn=o.tagName;
		if(o.tohide){
			if(faq.cssjs('check',o.tohide,faq.hideClass)){
				o.getElementsByTagName('img')[0].setAttribute('src', (tn=='H4')?faq.openPicH4:faq.openPicH5);
				o.getElementsByTagName('img')[0].setAttribute('alt', (tn=='H4')?faq.openAltH4:faq.openAltH5);
				o.setAttribute('title',(tn=='H4')?faq.openAltH4:faq.openAltH5);
				faq.cssjs('swap',o.tohide,faq.hideClass,faq.showClass);
				faq.cssjs('add',o,faq.triggeropen);
				faq.cssjs('remove',o,faq.trigger);
			}else{
				o.getElementsByTagName('img')[0].setAttribute('src',(tn=='H4')?faq.closedPicH4:faq.closedPicH5);
				o.getElementsByTagName('img')[0].setAttribute('alt',(tn=='H4')?faq.closedAltH4:faq.closedAltH5);
				o.setAttribute('title',(tn=='H4')?faq.closedAltH4:faq.closedAltH5);
				faq.cssjs('swap',o.tohide,faq.showClass,faq.hideClass);
				faq.cssjs('remove',o,faq.triggeropen);
				faq.cssjs('add',o,faq.trigger);
			}
			faq.currentOpen=o;
			faq.cancelClick(e);
			//document.getElementById('debug').innerHTML=o.tohide.className;
		}
		else{
			faq.cancelClick(e);
		}
	},
	/* helper methods */
	getTarget:function(e){
		var target = window.event ? window.event.srcElement : e ? e.target : null;
		if (!target){return false;}
		while(!target.tohide && target.nodeName.toLowerCase()!='body')
		{
			target=target.parentNode;
		}
		//if (target.nodeName.toLowerCase() != 'a'){target = target.parentNode;}
		return target;
	},
	cancelClick:function(e){
		if (window.event){
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			return;
		}
		if (e){
			e.stopPropagation();
			e.preventDefault();
		}
	},
	addEvent: function(elm, evType, fn, useCapture){
		if (elm.addEventListener) 
		{
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if (elm.attachEvent) {
			var r = elm.attachEvent('on' + evType, fn);
			return r;
		} else {
			elm['on' + evType] = fn;
		}
	},
	cssjs:function(a,o,c1,c2){
		switch (a){
			case 'swap':
				o.className=!faq.cssjs('check',o,c1)?o.className.replace(c2,c1):o.className.replace(c1,c2);
			break;
			case 'add':
				if(!faq.cssjs('check',o,c1)){o.className+=o.className?' '+c1:c1;}
			break;
			case 'remove':
				var rep=o.className.match(' '+c1)?' '+c1:c1;
				o.className=o.className.replace(rep,'');
			break;
			case 'check':
				return new RegExp("(^|\\s)" + c1 + "(\\s|$)").test(o.className)
			break;
		}
	}
}
faq.addEvent(window, 'load', faq.init, false);

function createPopup(x, y, titlebar, name, contents, message) {
	//alert( 'in createPopup' );
	var body = document.getElementsByTagName("body")[0]; 
	//alert( typeof body );
	var div = document.createElement("div");
	div.id = name + "-popup";
	div.style.position = "absolute";
	
	var leftpos = x + "px";
	var toppos  = y + "px";
	
	div.style.left = leftpos;
	div.style.top = toppos;
	div.style.zIndex = "100";
	contents = contents || "";
	message  = message || "";

	div.innerHTML = '<div id="' + name + '-title" class="popup-title">' + titlebar + '</div>' +
                        '<div id="' + name + '-contents" class="popup-contents">' + contents + '</div>' +
			'<div id="' + name + '-message" class="popup-message">' + message + '</div>';

	body.appendChild(div);
	div.className = "popup";
	//alert( div.toString() );
	return div;
}

function createPopupButtons() {
	var buttons = "";
	if (arguments.length > 0) {
		buttons = '<span class="buttons">';
	}
	for (var i=0; i<arguments.length; i++) {
		buttons =  buttons + "<span>" + arguments[i] + "</span>";
	}

	buttons = buttons + "</span>";
	return buttons;
}

function closePopup(id, refresh) {
	var el = $(id);
	if (el) {
		el.parentNode.removeChild(el);
	}
	if (refresh) {
		window.location.reload();
	}
}

function handleEnter(ev, func, arg) {
        if (!ev) {
                ev = window.event;
        }
        var code = ev.which || ev.keyCode;
        if (code == 13) { // return/enter
		func(arg);
                ev.returnValue = true;
                return true;
        }
        ev.returnValue = false;
        return false;
}


function moveByObjSize(div, addOffsetWidth, addOffsetHeight) {
	if (addOffsetWidth) {
		div.style.left = parseFloat(div.style.left || 0) + (addOffsetWidth * div.offsetWidth) + "px";
	}
	if (addOffsetHeight) {
		div.style.top = parseFloat(div.style.top || 0) + (addOffsetHeight * div.offsetHeight) + "px";
	}
}

function moveByXY(div, x, y) {
	if (x) {
		div.style.left = parseFloat(div.style.left || 0) + x + "px";
	}
	if (y) {
		div.style.top = parseFloat(div.style.top || 0) + y + "px";
	}
}

function getXYForId(id, addWidth, addHeight) {
	var div = $(id);
	var xy = Position.cumulativeOffset(div);
	if (addWidth) {
		xy[0] = xy[0] + div.offsetWidth;
	}
	if (addHeight) {
		xy[1] = xy[1] + div.offsetHeight;
	}
	return xy;
}

function toggleIntro(id, toggleid) {
	var obj = $(id);
	var toggle = $(toggleid);
	if (obj.className == 'introhide') {
		obj.className = "intro"
		toggle.innerHTML = "[-]";
	} else {
		obj.className = "introhide"
		toggle.innerHTML = "[+]";
	}
}

function tagsToggleStoryDiv(id, is_admin, type) {
	var bodyid = 'toggletags-body-' + id;
        var tagsbody = $(bodyid);
	if (tagsbody.className == 'tagshide') {
		tagsShowBody(id, is_admin, '', type);
	} else {
		tagsHideBody(id);
	}
}

function tagsHideBody(id) {
	// Make the body of the tagbox vanish
	var tagsbodyid = 'toggletags-body-' + id;
        var tagsbody = $(tagsbodyid);
	tagsbody.className = "tagshide"

	// Make the title of the tagbox change back to regular
	var titleid = 'tagbox-title-' + id;
        var title = $(titleid);
	title.className = "tagtitleclosed";

	// Make the tagbox change back to regular.
	var tagboxid = 'tagbox-' + id;
        var tagbox = $(tagboxid);
	tagbox.className = "tags";

	// Toggle the button back.
	var tagsbuttonid = 'toggletags-button-' + id;
        var tagsbutton = $(tagsbuttonid);
	tagsbutton.innerHTML = " ";
}

function tagsShowBody(id, is_admin, newtagspreloadtext, type) {

	type = type || "stories";

	//alert("Tags show body / Type: " + type );
	
	// Toggle the button to show the click was received
	var tagsbuttonid = 'toggletags-button-' + id;
        var tagsbutton = $(tagsbuttonid);
	tagsbutton.innerHTML = " ";

	// Make the tagbox change to the slashbox class
	var tagboxid = 'tagbox-' + id;
        var tagbox = $(tagboxid);
	tagbox.className = "tags";

	// Make the title of the tagbox change to white-on-green
	var titleid = 'tagbox-title-' + id;
        var title = $(titleid);
	title.className = "tagtitleopen";

	// Make the body of the tagbox visible
	var tagsbodyid = 'toggletags-body-' + id;
        var tagsbody = $(tagsbodyid);
	
	tagsbody.className = "tagbody";
	
	// If the tags-user div hasn't been filled, fill it.
	var tagsuserid = 'tags-user-' + id;
	var tagsuser = $(tagsuserid);
	if (tagsuser.innerHTML == "") {
		// The tags-user-123 div is empty, and needs to be
		// filled with the tags this user has already
		// specified for this story, and a reskey to allow
		// the user to enter more tags.
		tagsuser.innerHTML = "Retrieving...";
		var params = [];
		if (type == "stories") {
			params['op'] = 'tags_get_user_story';
			params['sidenc'] = id;
		} else if (type == "urls") {
			//alert('getting user urls ' + id);
			params['op'] = 'tags_get_user_urls';
			params['id'] = id;
		}
		params['newtagspreloadtext'] = newtagspreloadtext
		ajax_update(params, tagsuserid);
		//alert('after ajax_update ' + tagsuserid);

		// Also fill the admin div.  Note that if the user
		// is not an admin, this call will not actually
		// return the necessary form (which couldn't be
		// submitted anyway).  The is_admin parameter just
		// saves us an ajax call to find that out, if the
		// user is not actually an admin.
		if (is_admin) {
			var tagsadminid = 'tags-admin-' + id;
			params = [];
			if (type == "stories") {
				params['op'] = 'tags_get_admin_story';
				params['sidenc'] = id;
			} else if (type == "urls") {
				params['op'] = 'tags_get_admin_url';
				params['id'] = id;
			}
			ajax_update(params, tagsadminid);
		}

	} else {
		if (newtagspreloadtext) {
			// The box was already open but it was requested
			// that we append some text to the user text.
			// We can't do that by passing it in, so do it
			// manually now.
			var textinputid = 'newtags-' + id;
			var textinput = $(textinputid);
			textinput.value = textinput.value + ' ' + newtagspreloadtext;
		}
	}
}

function tagsOpenAndEnter(id, tagname, is_admin, type) {
	// This does nothing if the body is already shown.
	tagsShowBody(id, is_admin, tagname, type);
}

function reportError(request) {
	// replace with something else
	alert("error");
}

function tagsCreateForStory(id) {
	var toggletags_message_id = 'toggletags-message-' + id;
	var toggletags_message_el = $(toggletags_message_id);
	toggletags_message_el.innerHTML = 'Saving tags...';

	var params = [];
	params['op'] = 'tags_create_for_story';
	params['sidenc'] = id;
	var newtagsel = $('newtags-' + id);
	params['tags'] = newtagsel.value;
	var reskeyel = $('newtags-reskey-' + id);
	params['reskey'] = reskeyel.value;

	ajax_update(params, 'tags-user-' + id);

	// XXX How to determine failure here?
	toggletags_message_el.innerHTML = 'Tags saved.';
}

function tagsCreateForUrl(id) {
	var toggletags_message_id = 'toggletags-message-' + id;
	var toggletags_message_el = $(toggletags_message_id);
	toggletags_message_el.innerHTML = 'Saving tags...';

	var params = [];
	params['op'] = 'tags_create_for_url';
	params['id'] = id;
	var newtagsel = $('newtags-' + id);
	params['tags'] = newtagsel.value;
	var reskeyel = $('newtags-reskey-' + id);
	params['reskey'] = reskeyel.value;

	ajax_update(params, 'tags-user-' + id);

	// XXX How to determine failure here?
	toggletags_message_el.innerHTML = 'Tags saved.';
}

// helper functions
function ajax_update(params, onsucc, options, url) {
	var h = $H(params);

	if (!url)
		url = '/ajax.pl';

	if (!options)
		options = {};

	options.method = 'post';
	options.parameters = h.toQueryString();

	var ajax = new Ajax.Updater(
		{ success: onsucc },
		url,
		options
	);
}

function ajax_periodic_update(secs, params, onsucc, options, url) {
	var h = $H(params);
	
	if (!url) 
		url = '/ajax.pl';
		
	if (!options)
		options = {};

	options.frequency = secs;
	options.method = 'post';
	options.parameters = h.toQueryString();

	var ajax = new Ajax.PeriodicalUpdater({ success: onsucc }, url, options);
}

