var ebayReq;
IMGPATH = '/img/';

if (!("console" in window) || !("firebug" in console)) {
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

window.addEvent('domready', function() {

	//usage
	var labeledInputs = $ES('.labeled');
	labeledInputs.each(function(input) {
		
		if (input.getProperty('value') === '') input.setProperty('value', input.title);
		
		input.addEvent('focus', function() {
			this.removeClass('labeled');
			if (this.value == input.title) this.value = '';
			else this.select();
			
		});
		
		input.addEvent('blur', function() {
			if (this.value === '') {
				this.addClass('labeled');
				this.value = input.title;
			}
		});
		
	});
	
	// Attach getValue and setValue to form elements
	$$('input,select,textarea').each(function(elem) {
		
		$extend(elem, {
			'setValue': function(valueToSet) {

				if (this.tagName == 'SELECT') {
					for (var i=0; i<this.options.length; i++) {
						if (this.options[i].value == valueToSet) this.selectedIndex = i;
					}

				} else if (this.tagName == 'INPUT' && ['text','hidden','password'].contains(this.type)) {
					this.value = valueToSet;
					
				} else if (this.tagName == 'TEXTAREA') {
					this.value = valueToSet;
				}
			}
		});


		
	});	

	// FORM.fillFromHash()
	$ES('form').each(function(elem) {
		
		$extend(elem, {
			'fillFromHash': function(hash) {
				for (var z in hash) {
					var formElem = this[z];
					if (!formElem || !formElem.setValue) continue;
					else formElem.setValue(hash[z]);
				}
			}
		});
		
	});	
	
	
	var tabbed_submenus = $ES('.tabbed_submenu');
	if (tabbed_submenus) tabbed_submenus.each(function(ulElem) {
		$ES('li', ulElem).each(function(liElem) {
			
			var linkElem = $E('a', liElem);
			if (linkElem) {
				// Title weghalen, we gaan namelijk uitschuiven!
				linkElem.setProperty('title', '');
				
				// Uitschuif effect 
				if (!liElem.hasClass('current')) {
					linkElem.myEffect = new Fx.Tween(linkElem, {'property': 'padding-top', 'duration': 300, 'transition': 'back:out'});
					linkElem.addEvent('mouseover', function() {this.myEffect.stop(); this.myEffect.start(24);});
					linkElem.addEvent('mouseout', function() {this.myEffect.stop(); this.myEffect.start(8);});
					//linkElem.addEvent('click', function() {this.myEffect.stop(); this.myEffect.start(5);});
				}
			}
		});
	});

});

function fillFromHash(oFormObj, hash) {
	for (var z in hash) {
		var formElem = oFormObj[z];
		if (!formElem || !formElem.setValue) continue;
		else formElem.setValue(hash[z]);
	}
}
/*
var defaultShadowBoxOptions = {
	assetURL: 		'/js/shadowbox/',
	animSequence: 	'hw',
	viewportPadding: 25,
	handleLgImages: 'drag',
	loadingImage: 	'images/loading-white.gif',
	skin: {

        main:       '<div id="shadowbox_overlay"></div>' +
                    '<div id="shadowbox_container">' +
                        '<div id="shadowbox">' +
                            '<div id="shadowbox_body">' +
                                '<div id="shadowbox_body_inner"></div>' +
                                '<div id="shadowbox_loading"></div>' +
                            '</div>' +
                            '<div id="shadowbox_title">' +
                                '<div id="shadowbox_title_inner"></div>' +
                            '</div>' +

                            '<div id="shadowbox_toolbar">' +
                                '<div id="shadowbox_toolbar_inner"></div>' +
                            '</div>' +
                        '</div>' +
                    '</div>',

        loading:    '<img src="{0}" alt="{1}" />' +
                    '<span><a href="javascript:Shadowbox.close();">{2}</a></span>',

        counter:    '<div id="shadowbox_counter">{0}</div>',

        close:      '<div id="shadowbox_nav_close">' +
                        '<a href="javascript:Shadowbox.close();">{0}</a>' +
                    '</div>',

        next:       '<div id="shadowbox_nav_next">' +
                        '<a href="javascript:Shadowbox.next();">{0}</a>' +
                    '</div>',

        prev:       '<div id="shadowbox_nav_previous">' +
                        '<a href="javascript:Shadowbox.previous();">{0}</a>' +
                    '</div>'

        }
}
*/
var SECTIONS = {
	'home': {
		'color': 'orange',
		'slug': '',
		'entity_link_base': ''
	},
	'archive': {
		'color': 'blue',
		'slug': 'pinball/archive',
		'entity_link_base': '/pinball/archive/'
	},
	'community': {
		'color': 'purple',
		'slug': 'pinball/community',
		'entity_link_base': '/pinball/community/articles/'
	},
	'koog': {
		'color': 'red',
		'slug': 'pinball/koog',
		'entity_link_base': '/pinball/koog/articles/'
	},
	'my pinside': {
		'color': 'yellow',
		'slug': 'pinball/my-pinside',
		'entity_link_base': ''
	},
	'top 100': {
		'color': 'green',
		'slug': 'pinball/top-100',
		'entity_link_base': ''
	},
	'shop': {
		'color': 'pink',
		'slug': 'pinball/shop',
		'entity_link_base': ''
	}
};

/*
Function: 		initTabElements
Description: 	Creates tabs from an array of 'header' elements and an array of 'content' elements.
Parameters:		- headerElems : an array of header elements, these are the clickable 'tab headers'.
				- contentElems : an array of content elements, these are the 'tab bodies'.
				- eventHooks : an object containing hooks to some tab events.
Returns:		Nothing.
*/


var cMooTabs = new Class({

	initialize: function(headerElems, contentElems, options){
		
		// Parse options
		this.headerElems				= headerElems;
		this.contentElems				= contentElems;
		
		// Event hooks
		this.hooks = {};
		
		// Implement user override options
		$extend(this, options);
		
		this.build();
		
		return this;
	},
	
	build: function() {
		if (!this.headerElems || !this.contentElems) return alert('headerElems or contentElems are empty!');
	
		this.headerElems.each(function(tabHeaderElem, i) {
		
			tabHeaderElem.addEvent('click', function(e) {
				if (e) new Event(e).stop();
				this.openTab(tabHeaderElem.rel);
			}.bind(this));
			
		}.bind(this));
	},
	
	openTab: function(tabName) {
	
		// Find tabheader (elem) of tab to open
		this.currentTabHeader = this.headerElems.filter(function(elem) {
			return (elem.rel == tabName);
		})[0];
		
		if (!this.currentTabHeader) return this;
		
		// beforeChangeTab hook.
		if (this.hooks['beforeChangeTab'] && this.hooks['beforeChangeTab'](this.currentTabHeader.rel, this.currentTabHeader) !== true) return false;
		
		// Swap the 'current' class to the clicked element
		this.headerElems.each(function(elem, i) {elem.removeClass('current');});
		this.currentTabHeader.addClass('current');
		
		// Unhide target div, if it exists
		this.contentElems.each(function(elem) {
			elem.setStyle('display', (this.currentTabHeader.rel == elem.getProperty('id') || this.currentTabHeader.rel == elem.getProperty('name')) ? 'block' : 'none');
		}.bind(this));
		
		// afterChangeTab hook.
		if (this.hooks['afterChangeTab']) this.hooks['afterChangeTab'](this.currentTabHeader.rel, this.currentTabHeader);
		
		return this;

	}
});



function setEbayCountry(countryCode, triggerElem) {
	//alert('Setting preferred country to ' + countryCode);
	
	if (!countryCode) countryCode = Cookie.read('pinside_ebay_countrycode');
	if (!countryCode) countryCode = 'auto';
	
	$$('A.countryFlag').each(function(linkElem) {
		if (!triggerElem) triggerElem = linkElem;
		if (linkElem.get('name') == countryCode) linkElem.addClass('selected');
		else linkElem.removeClass('selected');
	});
	
	var myCookie = Cookie.write('pinside_ebay_countrycode', countryCode, {
//		domain: 'pinside.com',
		path: '/',
		duration: 30,
		secure: false
	});
	
	// Find the flagDivElem that belongs to the flag that was clicked.	
	var flagDivElem = triggerElem.getParent('div.flagDiv');
	
	// The flagDivElem may contain a reference (id) to the ebay_items div belonging to it.
	if (flagDivElem.get('rel') != '') targetElem = $(flagDivElem.get('rel'));
	if (!targetElem) targetElem = flagDivElem.getNext('.ebay_items') || $$('.ebay_items')[0];
	if (!targetElem) return console.error('triggerElemParent not found');
	
	// The targetElem may contain ajax request options (as a json-string) in its 'rel' property
	var divSpecificOptions = (targetElem.get('rel') != '') ? JSON.decode(targetElem.get('rel')) || {} : {};
	divSpecificOptions.country_abbrev = countryCode;
	divSpecificOptions.token = token;
	
	if (ebayReq) ebayReq.cancel();
	targetElem.setStyle('height', targetElem.getHeight() - 10);
	targetElem.addClass('ebay_items_loading').set('html', '&nbsp;')
	
	ebayReq = new Request({
		url: '/api/pinsideitems/getItems_realtime',
		link: 'cancel',
		data: divSpecificOptions,
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			targetElem.set('html', oData.html).removeClass('ebay_items_loading');
		},
		'onFailure': defaultFailureFunction

	}).send();

	return false;
}

function toggleFlagOptions(flagDivElem) {
	var elemToMorph = $(flagDivElem).getElement('.flagDivInner');
	elemToMorph.toggleClass('flag-div-opened');
	
	var nHeight = elemToMorph.hasClass('flag-div-opened') ? elemToMorph.getFirst().getHeight() : 0;

	elemToMorph.morph({height: nHeight});
	return false;
}

function gotoTab(id) {
	var tab = $(id);
	if (tab && tab.fireEvent) tab.fireEvent('click');
	return false;
}

function manageCollectionnotLoggedInError() {
	alert('To add machines to your wishlist or collection, you must have a Pinside account and be logged in. Taking you to the register/log in page now...');
}

function defaultFailureFunction(oXHR) {
	var oData = evaluateJsonString(oXHR.responseText);
	if (oData.errors) alert(oData.errors.join('\n'));
	else alert('Hey, an error occurred!');
}

function navToFirstLinkInElem(e) {
	var linkElem = $E('a', this);
	if (linkElem) {
		window.location = linkElem.href;
		new Event(e).stop();
	}
}

function regexMatchOrDefault(str, regexpObj, noMatchDefault) {
	var matched = str.match(regexpObj);
	return matched ? matched[1] : noMatchDefault;
}

function findParentByClassName(className, startElem) {
	while (!startElem.hasClass(className) && startElem.tagName != 'body') startElem = startElem.parentNode;
	return (startElem.tagName != 'body') ? startElem : null;
}

function reportError(oHeader) {
	console.dir(oHeader);
}

/*
Function: getQuote
	Returns a quote from the databse.

Arguments:
	type_or_id - A numeric or string value
		* When a type is given, e.g. 'slogan' then a random quote of that type is fetched.
		* When the id of an existing quote is given, e.g. 123, then the next quote of that type is given. E.g. quote with id 124.

Returns:
	Object containing a new id and quote.
	E.g. {'124': 'A new quote here...'}
*/
function getQuote(quote_type, quote_linkid, quote_afterkey, container, quoteTypeContainer, quoteLinkElem) {
	var container = $(container);
	var quoteTypeContainer = $(quoteTypeContainer);
	var quoteLinkElem = $(quoteLinkElem);
	
	var myApiCallData = {
		'token':				token,
		'quote_type': 			quote_type,
		'quote_linkid': 		quote_linkid
	};
	
	// Add an exclude list?
	if (quote_afterkey && !document.shownQuotesList) document.shownQuotesList = quote_afterkey;
	if (document.shownQuotesList) myApiCallData['quote_excludekeys'] = document.shownQuotesList;
	
	if (container) {
		container.getParent().setStyle('background', 'transparent url(' + IMGPATH + 'ajaxload/quote_load.gif) no-repeat center center');
		container.effect('opacity', {'onComplete':function() {

			var myApiCall = new Ajax('/api/pinsidequotes/get', {
				'data':			myApiCallData,
				'autoCancel':	true,
				'onSuccess': function(str) {
					var oData = evaluateJsonString(str);
					setQuote(oData, container, quoteTypeContainer, quoteLinkElem);
				},
				'onFailure': defaultFailureFunction

			}).request();
		
		}}).start(0);
	}
	

	
	return false;
}

/*
Function: getTrivia
	Returns a random fun fact from the databse.

Arguments:
	imageID - id of element to put new image in
	textID - id of element to put new func fact text in
	linkID - id of element linking to machine

*/
function getTrivia(containerID) {
	
	var container = $(containerID);
	if (!container) return;
	
	var myApiCallData = {
		'token':				token
	};
	
	// Add an exclude list?
	if (!document.shownTriviaList) document.shownTriviaList = [];
	if (document.shownTriviaList) myApiCallData['exclude_machines'] = document.shownTriviaList;
	
	if (container) {
		container.getParent().setStyle('background', 'transparent url(' + IMGPATH + 'ajaxload/quote_load.gif) no-repeat center center');
		container.effect('opacity', {'onComplete':function() {
			
			container.getElement('.triviaImage').setProperty('src', '/img/pix.gif');
			
			var myApiCall = new Ajax('/api/pinsideSearch/getRandomTrivia', {
				'data':			myApiCallData,
				'autoCancel':	true,
				'onSuccess': function(str) {
					var oData = evaluateJsonString(str);
					if (oData.selected_comments.length == 0) {
						document.shownTriviaList = [];
						getTrivia(containerID);
					}
					else setTrivia(oData, container);
				},
				'onFailure': defaultFailureFunction

			}).request();
		
		}}).start(0);
	}
	

	
	return false;
}

function prepareAdCollapsers() {
	$$('A.collapser-trigger').each(function(obj) {
		
		obj.addEvent('click', function(e) {
			var ev = new Event(e).stop();
			
			var par = obj.getParent();
			var collapser = par.getElement('.ad-collapser');
			var collapserInner = par.getElement('.ad-collapser-inner');
			
			if (collapser.hasClass('ad-collapser-closed')) {
				obj.setHTML('&raquo; Hide ad details');
				var myEffect = new Fx.Morph(collapser, {duration:500, transition:'bounce:out', onComplete: function() {
					collapser.removeClass('ad-collapser-closed');
				}}).start({'height': collapserInner.getHeight()});
				
			} else {
				obj.setHTML('&raquo; Show ad details');
				var myEffect = new Fx.Morph(collapser, {duration:500, transition:'quint:out', onComplete: function() {
					collapser.addClass('ad-collapser-closed');
				}}).start({'height': 0.1});
				
			}
		});
	
	});

}

// For JW Slideshow
function getUpdate(typ,pr1,pr2,pid) {
	//console.info(typ,pr1,pr2,pid);
	if(typ == "item") {
		
		var captionDiv 	= $(pid + '_caption_div');
		if (!captionDiv) return;
		
		
		var itemData 		= thisMovie(pid).itemData(pr1);
		//console.dir(itemData);
		
		if (captionDiv.getProperty('name') == itemData['title']) return;
		else captionDiv.setProperty('name', itemData['title']);
		
		var div 			= new Element('div').addClass('content bordered').setStyles({'height': 1, 'overflow': 'hidden', 'display': 'none'});
		var headerElem		= new Element('h2').addClass('fat-box-title').injectInside(div);
		var linkElem		= null;
		
		// Linked?
		if (itemData['link'] && itemData['category'] && SECTIONS[itemData['category']]) {
			//var url = SECTIONS[itemData['category']]['entity_link_base'] + itemData['link'];
			var url = itemData['link'];
			var newwindow = false;
		} else if (itemData['link']) {
			var url = itemData['link'];
			var newwindow = true;
		} else {
			var url = null;
		}
		
		// If url
		if (url) {
			linkElem = new Element('a').setProperties({'href': url, 'target': (newwindow ? '_blank' : '_same')}).injectInside(headerElem);
			div.setStyle('cursor', 'pointer').addEvent('click', function(e) {
				new Event(e).stop();
				//if (newwindow) window.open(url);
				//else location.href = url;
				location.href = url;
			});
		}

		
		// Insert stuff we know
		if (itemData['category']) 					div.addClass('heading-' + SECTIONS[itemData['category']]['color']);
		if (itemData['title'])  					new Element('span').setHTML(itemData['title']).injectInside(linkElem || headerElem);
		if (itemData['author'] && itemData['id'])	new Element('span').addClass('heading-black').setStyles({'font-size': '0.90em', 'display':'block'}).setHTML('By ' + itemData['author'] + ', ' + itemData['id']).injectInside(linkElem || headerElem);
		if (itemData['description'])				new Element('p').setHTML(itemData['description']).injectInside(div);

		div.injectTop(captionDiv);
		
		(function() {
			div.setStyle('display', 'block');
			div.effect('height', {'onComplete': function() {
				captionDiv.getLast().empty().remove();
			}}).start(captionDiv.offsetHeight);
		}).delay(500);
	}
};

// This is a javascript handler for the player and is always needed.
function thisMovie(movieName) {
    if(navigator.appName.indexOf("Microsoft") != -1) {
		return window[movieName];
	} else {
		return document[movieName];
	}
};

function setQuote(oData, container, quoteTypeContainer, quoteLinkElem) {
	if (oData['success'] == 1) {
		
		var fontSize = 130 - (oData['quote_value'].length) / 3;
		if (container) {
			container.setStyles({'font-size': fontSize + '%'}).setProperties({
				'name': oData['quote_id'],
				'title': oData['quote_value'],
				'href': 'pinball/archive/' + oData['quote_machine_slug']
			}).setHTML('&quot;' + oData['quote_value'] + '&quot;');
			container.getParent().setStyle('background', 'none');
			container.effect('opacity').start(1);
		}
		if (quoteTypeContainer) {
			quoteTypeContainer.setHTML(oData['quote_type']);
		}
		if (quoteLinkElem) {
			quoteLinkElem.setProperty('href', 'pinball/archive/' + oData['quote_machine_slug']);
		}
		document.shownQuotesList = oData['quote_excludekeys'];
	}
}

function setTrivia(oData, container) {

	if (!container) return;
	
	var imageElem = container.getElement('.triviaImage');
	var textElem = container.getElement('.triviaText');
	var linkElements = container.getElements('.triviaLink');

	if (oData['success'] == 1) {
		
		container.getParent().setStyle('background', 'none');
		container.effect('opacity').start(1);
		
		imageElem.setProperty('src', oData.image_rel_path);
		linkElements.setProperty('href', '/pinball/archive/' + oData.slug_name);
		textElem.setProperty('html', oData.selected_comments.getRandom());
		
		//if (quoteLinkElem) quoteLinkElem.setProperty('href', 'pinball/archive/' + oData['quote_machine_slug']);

		document.shownTriviaList = oData['excluded_machines'];
	}
}

function loadQuoteEditor(container, mode, entityId) {
	container = $(container);
	if (!container) return false;
	
	var previousValue   = container.getProperty('title');
	var previousId		= container.getProperty('name');
	
	container.setProperty('title', '').setHTML('');

	if (mode == 'add') {	
		var typeCombo = new Element('select').injectInside(container);
		typeCombo.options[0] = new Option('quote',	'quote');
		typeCombo.options[1] = new Option('slogan',	'slogan');
	}
		
	var ta = new Element('textarea').setStyles({'display':'block', 'height':'42px', 'overflow':'auto'}).injectInside(container);
	if (mode == 'edit') ta.setProperty('value', previousValue);

	new Element('input').setProperties({'type': 'button', 'value': 'cancel'}).addEvent('click', function() {
		setQuote({'success': 1, 'quote_value': previousValue, 'quote_id': previousId}, container);
	}).injectInside(container);
	
	new Element('input').setProperties({'type': 'button', 'value': 'save'}).addEvent('click', function() {
		var newValue = ta.value;
		
		if (newValue != previousValue) {
			
			if (mode == 'add') var queryData = {
				'token': token,
				'quote_linkid': entityId,
				'quote_value': newValue,
				'quote_type': typeCombo.options[typeCombo.selectedIndex].value
			};
			
			if (mode == 'edit') var queryData = {
				'token': token,
				'quote_key': previousId,
				'quote_value': newValue
			};
			
			new Ajax('/api/pinsidequotes/store', {
				'data': queryData,
				'onSuccess': function(str) {
					var oData = evaluateJsonString(str);
					setQuote({'success': 1, 'quote_value': oData['quote_value'], 'quote_id': oData['quote_key']}, container);
				},
				'onFailure': defaultFailureFunction
			}).request();
			
		} else {
			setQuote({'success': 1, 'quote_value': previousValue, 'quote_id': previousId}, container);
		}
		
	}).injectInside(container);
	
	
	return false;
}

function insertCollectionItem(machine_key, status, refreshElem) {
	new Ajax('/api/pinsideCollection/insertCollectionItem', {
		'data': {
			'token': token,
			'collection_machine': machine_key, 
			'collection_status': status
		},
		'onComplete': function(str) {
			var oData = evaluateJsonString(str);
			if (oData.success==1) {
				
				if (refreshElem) {
					var fx = new Fx.Morph(refreshElem, {duration: 1000, transition: Fx.Transitions.Quart.easeOut});
					
					var theText = oData.result_text + ' <a href="/pinball/my-pinside/collection">(manage my collection)</a>';
					
					fx.start({'opacity': 0}).chain(function(){
						refreshElem.setHTML(theText);
						this.start({
							'opacity': 1
						});
					});
				}
					
			}
		},
		'onFailure': defaultFailureFunction
	}).request();
	return false;
}

function evaluateJsonString(str) {
	var oReturn;
	
	try {
		//oReturn = eval('(' + str + ')');
		oReturn = Json.evaluate(str);
			
	} catch(err) {
		oReturn = {
			'success': 0,
			'errors': ["evaluateJsonString could not evaluate the passed string: " + str]
		};
	}
	
	return oReturn;
	
}

function showQuickLoginForm(e) {
	
	new Event(e).stop();
	
	var loginLinkElem = $('loginLink');
	var loginLinkTargetElem = $('loginLinkTarget');
	var loginLinkTextElem = $('loginLinkText');
	
	
	loginLinkTextElem.setHTML('Your username and password: ');
	
	loginLinkElem.effects({}).start({
		'opacity': 0,
		'width': 1,
		'margin-left': 0
	});
	
	loginLinkTargetElem.effects({'duration':500,'onComplete': function() {
		$('quick_login_field').focus()
	}}).start({
		'width': 150,
		'margin-left': 6
	});
	return false;
}

function showQuickSearch(e) {
	
	new Event(e).stop();
	
	var quicksearchLinkElem = $('quickSearchLink');
	var quickSearchLinkTargetElem = $('quickSearchLinkTarget');
	
	quicksearchLinkElem.setHTML('Keyword: ');
	quickSearchLinkTargetElem.effects({'duration':500,'onComplete': function() {
		$('quick_search_field').focus()
	}}).start({
		'width': 150,
		'margin-left': 6
	});
	
	return false;
}

function userLogin(oForm, successRedirectUrl) {
	
	if (!successRedirectUrl && login_redirect_url) successRedirectUrl = login_redirect_url;
	
	var submitButton = $E('button[type=submit]', oForm);
	setButtonWaitState(submitButton, true);
	
	new Ajax('/api/pinsideusers/login', {
		'data': oForm,
		'onSuccess': function(str) {
			setButtonWaitState(submitButton, false);
			window.location.href = successRedirectUrl || window.location.href;
		},
		'onFailure': function(oXHR) {
			setButtonWaitState(submitButton, false);
			defaultFailureFunction(oXHR);
		}
			
	}).request();
	return false;
	
}

function userLogout() {
	new Ajax('/api/pinsideusers/logout', {
		'data': {'token': token || ''},
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			location.href = location.href;
		},
		'onFailure': defaultFailureFunction
	}).request();
	return false;
}

function storeComment(oForm) {
	new Ajax(oForm.action, {
		'data': oForm,
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			//console.dir(oData);
			
			var commentListElem = $('commentsList');
			var existingCommentNode = $('comment-' + oData.comment_key);
			var commentFormElem = $('commentsForm');
			
			if (!isNaN(oData.comment_key) && commentListElem) {
				
				var commentElem = getCommentItemMarkup(oData);
				
				if (existingCommentNode) {
					commentElem.setStyle('background-color', '#FFC124')
					existingCommentNode.replaceWith(commentElem);
				}
				else {
					commentElem.setStyle('background-color', '#3AEC5C')
					commentElem.injectInside(commentListElem);
				}
				
				commentElem.effect('background-color', {'duration':1500}).start('#ffffff');
				new Fx.Scroll(window).toElement(commentElem);
				
				commentFormElem.reset();
				commentFormElem['comment_key'].value = -1;
				commentFormElem['submitButton'].value = "Add comment";
			
				$('commentListForm_add').setStyle('display', 'block');
				$('commentListForm_edit').setStyle('display', 'none');
				
				if ($('commentListForm_antiSpam')) {
					$('commentListForm_antiSpam').setStyle('display', 'block');
				
					var antiSpamInput = $E('input', 'commentListForm_antiSpam');
					if (antiSpamInput) antiSpamInput.setProperty('value', '').fireEvent('blur');
				}

				
			} else location.href = location.href;
		},
		'onFailure': function(oXHR) {
			var antiSpamInput = $E('input', 'commentListForm_antiSpam');
			if (antiSpamInput) antiSpamInput.setProperty('value', '').fireEvent('blur');
			defaultFailureFunction(oXHR);
		}
	}).request();
	return false;
}


function editComment(id) {
	new Ajax('/api/pinsideArticles/getComments', {
		'data': {'comment_key': id, 'token': token || ''},
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			var oComment = oData['comment_list'][0];
			//console.dir(oComment);
			
			var commentFormElem = $('commentsForm');
			commentFormElem.fillFromHash(oComment);
			commentFormElem['submitButton'].value = "Save changes to comment";
			
			$('commentListForm_add').setStyle('display', 'none');
			$('commentListForm_edit').setStyle('display', 'block');
			
			if ($('commentListForm_antiSpam')) {
				$('commentListForm_antiSpam').setStyle('display', 'none');
			}
			
			new Fx.Scroll(window).toElement(commentFormElem);
			
		},
		'onFailure': defaultFailureFunction
	}).request();
	return false;
}

function deleteComment(id) {
	new Ajax('/api/pinsideArticles/deleteComment', {
		'data': {'comment_key': id, 'token': token || ''},
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			var existingCommentNode = $('comment-' + oData.comment_key);
		
			if (existingCommentNode) {
				existingCommentNode.effects({
					'duration':700,
					'onComplete': function() {if (existingCommentNode) existingCommentNode.empty().remove();}
				}).start({
					'background-color': ['#FF3824', '#ffffff'],
					'height': 1
				});
			
			} else location.href = location.href;
			
		},
		'onFailure': defaultFailureFunction
	}).request();
	return false;
}


function formToHash(oForm) {
	var hash = {};
	
	$ES('input[name],select[name],textarea[name]', oForm).each(function(formElem) {
		
		var elemValue = '';
		
		//console.info(formElem, formElem.tagName, formElem.value);
		//alert(formElem);
		
		if (formElem.get('tag') == 'select') elemValue = formElem.options[formElem.selectedIndex].value;
		else if (formElem.get('tag') == 'input' && formElem.get('type') == 'checkbox') elemValue = formElem.checked ? 1 : 0;
		else if (formElem.get('tag') == 'input') elemValue = formElem.value;
		else if (formElem.get('tag') == 'textarea') elemValue = formElem.value;
		
		
		if (!formElem.hasClass('labeled')) hash[formElem.name] = elemValue; 
	}); 
	
	return hash;
}

function fillComboOptions(comboObj, optionsArray) {
	if (comboObj) comboObj.setHTML();
	if ($type(optionsArray) != 'array') return;
	
	for (var i=0; i<optionsArray.length; i++) {
		new Element('option').setProperty('value', optionsArray[i]).setHTML(optionsArray[i]).injectInside(comboObj);
	}
}

function getImagePath(imageHash, versionName, nocache) {
	
	var imageSha	= (imageHash['image_sha1']) ? imageHash['image_sha1'] : '';
	var imageCat	= (imageHash['image_linktype']) ? imageHash['image_linktype'] : 'archive';
	var imageExt	= (imageHash['image_extension']) ? imageHash['image_extension'] : 'jpg';
	var nocachestr = (nocache ? '?nocache=' + Math.round(Math.random(0,1) * 10000000) : '');
	
	if (imageSha && imageCat && versionName) return imageCat + "/" + imageSha.substr(0, 2) + "/" + versionName + "/" + imageSha + "." + imageExt + nocachestr;
	else return '';
}

function getCommentItemMarkup(commentData) {
	
	var oLi		= new Element('li').setProperty('id', 'comment-' + commentData.comment_key);
	var oImg	= new Element('img').setProperty('src', commentData.comment_create_user_avatar.avatar_tinythumb_path).addClass('avatar').injectInside(oLi);
	var oMetaP	= new Element('p').addClass('comment-meta').injectInside(oLi);
	
	if (commentData.comment_create_user == 1000) {
		new Element('span').addClass('user-name').setHTML(commentData.comment_anonymous_name).injectInside(oMetaP);
		oMetaP.appendText(' (anonymous)');
	} else {
		new Element('a').setProperties({'href': '#', 'target': '_blank'}).addClass('user-name').setHTML(commentData.user_name).injectInside(oMetaP);
	}
	
	oMetaP.appendText(' commented on ' + commentData.comment_create_date + ' (');
	
	new Element('a').setProperties({'href': '#'}).setHTML('edit').addEvent('click', function(e) {
		new Event(e).stop();
		return editComment(commentData.comment_key);
	}).injectInside(oMetaP);
	
	oMetaP.appendText(' | ');
	
	new Element('a').setProperties({'href': '#'}).setHTML('delete').addEvent('click', function(e) {
		new Event(e).stop();
		return (window.confirm('Are you sure you want to delete this comment?')) ? deleteComment(commentData.comment_key) : false;
	}).injectInside(oMetaP);
	
	oMetaP.appendText(' )');
	
	var oTextP	= new Element('p').addClass('comment-text').setHTML(commentData.comment_text).injectInside(oLi);
	
	return oLi;
} 

function encodeAsJsonString(obj) {
	var str = obj ? Json.toString(obj) : '';
	return '[' + str + ']';
}

/**
 * Observer - Observe formelements for changes
 *
 * @version		1.0rc1
 *
 * @license		MIT-style license
 * @author		Harald Kirschner <mail [at] digitarald.de>
 * @copyright	Author
 */
var Observer = new Class({

	options: {
		periodical: false,
		delay: 1000
	},

	initialize: function(el, onFired, options){
		this.setOptions(options);
		this.addEvent('onFired', onFired);
		this.element = $(el);
		this.listener = this.fired.bind(this);
		this.value = this.element.getValue();
		if (this.options.periodical) this.timer = this.listener.periodical(this.options.periodical);
		else this.element.addEvent('keyup', this.listener);
	},

	fired: function() {
		var value = this.element.getValue();
		if (this.value == value) return;
		this.clear();
		this.value = value;
		this.timeout = this.fireEvent.delay(this.options.delay, this, ['onFired', [value]]);
	},

	clear: function() {
		$clear(this.timeout);
		return this;
	}
});

Observer.implement(new Options);
Observer.implement(new Events);

/* -----------------------------------------------------------------------------
	mooButton
----------------------------------------------------------------------------- */

var cMooButton = new Class({

	initialize: function(options) {
		this.window				= self;
		this.tooltip 			= '';						// Text that appears when user hovers over this button
		this.icon				= '';						// Icon for this button. The buttons window iconImagePath property will automatically be prefixed if no / is found at char 0
		this.icon_hover			= null;						// And optionally an onhover version of this icon
		this.iconcolor			= null;						// Bg color name behind the icon
		this.action				= null;						// function to perform when this button is clicked
		this.eventAction		= null;						// function to perform when this button is clicked, but this one passes the click event
		this.enabled			= true;						// Is the button in enabled state?
		this.disableOnClick		= false;					// disable button after clicking to avoid clicking multiple times
		this.closeWindow		= false;					// If set to true, buttons parent window will close after performing the button action
		this.submitWindowForm 	= false;					// If set to true, buttons parent window's form will be submitted after performing the button action
		this.caption 			= '';						// Button text
		this.type				= 'text';					// Button type: 'text' for a regular INPUT, or 'image' to use an image as button
		this.className			= 'btn_swiss';		// Button class
		this.id					= null;
		this.hidden				= false;
		this.fixedWidth			= 0;
		this.floating			= null;
		this.showAdvancedTooltips	= false;
		
		// Overwrite with any props set in 'options'
		Object.extend(this, options);
		
		// fix paths for icons?
		if (this.icon && this.icon.substr(0,1) != '/') this.icon = this.window.iconImagePath + this.icon;
		if (this.icon_hover && this.icon_hover.substr(0,1) != '/') this.icon_hover = this.window.iconImagePath + this.icon_hover;
	},
	
	build: function() {

		switch (this.type) {
			case 'text': 	this.renderTextualButton(); break;
			case 'icon':	this.renderImageButton(); break;

			default: alert('invalid button type specified: ' + this.type); return null;
			
		}
		
		if (this.hidden) this.button.setStyle('display', 'none');
		if (this.floating) this.button.setStyle('float', this.floating);
		
		if (this.tooltip ) {
			if (this.showAdvancedTooltips) {
				this.button.addEvent('mousemove', this.moveTooltip.bind(this));
				this.button.addEvent('mouseout', this.hideTooltip.bind(this));
			} else this.button.setProperty('title', this.tooltip);
		}
				
		this.button.addEvent('click', function(e) {
			if (this.disabled) return;
			this.hideTooltip();
			if (this.clicked) return this.button;
			
			if (this.disableOnClick) this.disableButton(true);
			
			// 'Normal' action
			if ($type(this.action) == 'string') 		eval(this.action);
			else if ($type(this.action) == 'function') 	this.action(this.window.formElem, this.button, e);
			
			// Event action
			if ($type(this.eventAction) == 'function') 	this.eventAction(e);
			
			if (this.closeWindow) 					this.window.closeWindow();
			if (this.submitWindowForm) 				this.window.submitWindowForm();
		}.bind(this));
		
		if (!this.enabled) this.disableButton(); 
		
		return this;
	},
	
	
	moveTooltip: function(e) {
		if (this.disabled) return;
		var ev = new Event(e);
		if (this.tooltipDiv) this.tooltipDiv.setStyles({'left': ev.page.x + this.showAdvancedTooltips.x - (this.tooltipDiv.offsetWidth / 2), 'top': ev.page.y + this.showAdvancedTooltips.y});
		else {
			this.tooltipDiv = new Element('div').addClass('editButtonTooltip').injectInside(document.body);
			this.tooltipDivText = new Element('div').setHTML(this.tooltip).injectInside(this.tooltipDiv);
			this.tooltipDiv.setStyle.delay(1000, this.tooltipDiv, ['visibility', 'visible']); 
		}

	},	
	
	hideTooltip: function() {
		if (this.tooltipDiv) {
			this.tooltipDiv.empty().remove();
			this.tooltipDiv = null;
		}
	},
	
	enableButton: function() {
		this.clicked = false;
		this.disabled = false;
		if (!Window.ie) this.button.setStyle('opacity', 1);
		this.button.removeClass('disabledbutton');
	},
	
	disableButton: function(clicked) {
		this.clicked = clicked;
		this.disabled = true;
		this.button.addClass('disabledbutton');
		if (!Window.ie) this.button.setStyle('opacity', .5);
		
		
		//if (clicked) this.enableButton.delay(5000, this); // Re-enable the button after a click, in case the submit failed and we want to submit again. This is kind of a development thing.
	},	
	
	renderTextualButton: function() {
		this.button = new Element('a').addClass(this.className).setProperties({
			'id': this.id,
			'href': '#'
		});
		
		var iconHost = new Element('div').addClass('icon').injectInside(this.button);
		if (this.iconcolor) iconHost.addClass(this.iconcolor);
		
		var iconElem = new Element('img').setProperty('src', this.icon).injectInside(iconHost);
		var textHost = new Element('div').addClass('text').appendText(this.caption).injectInside(this.button);
		
		if (this.fixedWidth > 0) this.button.setStyle('width', this.fixedWidth);
	},
	
	/*
	OLD_renderTextualButton: function() {
		
		this.button = new Element('div').addClass(this.className);
		this.button.id = this.id;
		
		this.iconContentSpan = new Element('span').injectInside(this.button);
		if (this.fixedWidth > 0) this.iconContentSpan.setStyle('width', this.fixedWidth);

		// If an icon is specified well inject an image in the span element
		if (this.icon) {
			this.iconContentSpan.addClass('withIcon');
			this.iconImage = new Element('IMG').addClass('image').setProperties({'src': this.icon}).injectInside(this.iconContentSpan);
		}
		
		if (this.caption != '') this.iconContentSpan.appendText(this.caption);
		else {
			this.button.setStyle('padding-right', 5);
			this.iconImage.setStyle('margin-right', 0);
		}
	},
	*/
	
	renderImageButton: function() {
		this.button = new Element('div').addClass('mooButton');
		this.button.id = this.id;

		var inner = new Element('IMG').addClass('image');
		if (this.className) inner.addClass(this.className);
		inner.setProperties({'src': this.icon});
		
		if (this.icon_hover) {
			inner.addEvent('mouseover', function() {inner.src = this.icon_hover;}.bind(this));
			inner.addEvent('mouseout', function() {inner.src = this.icon;}.bind(this));
		}
		
		inner.injectInside(this.button);
	}
	
});

function renderIcon(src, alt) {
	
	var icon 	= new Element('DIV', {
		'title': 	alt || '',
		'class':	'icon',
		'styles':	{'background-image': 'url(' + src + ')'}
	}); 
	
	return icon;
}


function parseJsonResponse(sResponse) {
	var sError, oResult;
	try {
		oResult = eval('('+sResponse+')');	
	} catch(err) {
		sError = 'Your response could not be evaluated:<br /><br />' + sResponse;
	}
	if (!sError && $type(oResult) == 'object' && oResult.success != 1) sError = oResult.errors.join('<br /><br />');

	if (sError) reportError('Error while parsing JSON response', sError);
	else {
		//if (oResult && oResult.debug) reportError('Debug information', oResult.debug);
		return oResult;
	}
	return false;
}

function reportError(header, error) {
	if (!header) header = 'Error!';
	if (top.mooWindoze) new top.mooWindoze().error(header, error);
	else {
		error = error.replace(/\<br \/\>/g, '\n');
		alert(header + '\n' + error);
	}
}

function getFormElementValue(elem) {
	var elem = $(elem);
	if (elem) return $type(elem) == 'select' ? elem.options[elem.selectedIndex].value : elem.value;
}


// QueryString parser object.
// Usage: 		var q = new Querystring([optional_querystring]);
// And then: 	alert(q.get(valueName));
function Querystring(qs) { // optionally pass a querystring to parse
	var params = new Hash();
	params.getValue = function(key, vdefault) {
		return params.get(key) || vdefault;
	}.bind(this)
		
	if (!qs) qs = location.search.substring(1, location.search.length);
	if (qs.length == 0) return params;

	// Turn <plus> back to <space>
	// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
	qs = qs.replace(/\+/g, ' ')
	var args = qs.split('&') // parse out name/value pairs separated via &
	
	// split out each name=value pair
	for (var i=0; i<args.length; i++) {
		var pair = args[i].split('=');
		var name = unescape(pair[0]);
		var value = (pair.length == 2)  ? unescape(pair[1]) : name;
		params.set(name, value);
	}
	
	return params;

}


function getDataAndBuildTable(oForm, targetElem, selectedKeyColumnValue) {
	
	if (targetElem) targetElem = $(targetElem);
	else targetElem = $(oForm.name + 'TargetDiv');
	if (!$(targetElem)) {alert('Error finding the target element'); return false;}
	
	targetElem.setHTML('').setStyle('background', 'url(/img/ajaxload/admin_load.gif) no-repeat center center');
	
	new Ajax(oForm.action, {
		'data': oForm,
		'onSuccess': function(str) {
			var oData = evaluateJsonString(str);
			targetElem.setHTML('').setStyle('background', '');
			
			// Build the table!
			if (oData['list']) var myTable = buildDataTable(tableConfigs[oForm.name], oData, oForm, selectedKeyColumnValue);
			if (myTable) {
				myTable.injectInside(targetElem);
				targetElem.setStyle('height', myTable.offsetHeight + 10);
			}
		},
		'onFailure': function(oXHR) {
			targetElem.setHTML('').setStyle('background', '');
			defaultFailureFunction(oXHR);
		}
	}).request();
	
	return false;
}

function buildDataTable(oTableConfig, oData, oForm, selectedKeyColumnValue) {

	if (!oTableConfig) return alert('No table config made for this table! Please make a table config named \'' + oForm.name + '\'.');
	
	// Build table
	var oTable		= new Element('table').addClass(oTableConfig.colorscheme);
	
	// Build colgroup?
	
	if (oTableConfig.generatecolgroup == true) {
		var oColgroup	= new Element('colgroup').injectInside(oTable);
		for (var z in oTableConfig.fields) {
			new Element('col').setProperty('width', oTableConfig.fields[z].width).injectInside(oColgroup);
		}
	}
	

	// Build headers
	var oTbody		= new Element('tbody').injectInside(oTable);
	var totalSpanCounter = 0;
	var oHeadRow	= new Element('tr').injectInside(oTbody);
	for (var z in oTableConfig.fields) {
		var oHeader = new Element('th').setHTML(oTableConfig.fields[z].caption).injectInside(oHeadRow);
		totalSpanCounter ++;
	}

	// Build data rows
	oData['list'].each(function(oDataItem, nCounter) {
		
		var oNormalRow = new Element('tr').injectInside(oTbody);
		if (nCounter % 2 == 0) oNormalRow.addClass('odd');
		if ($type(oTableConfig.onclick) == 'function') oNormalRow.addEvent('click', oTableConfig.onclick.pass([oDataItem, oNormalRow]));
		
		oNormalRow.addEvent('mouseover', function() {this.addClass('hover');});
		oNormalRow.addEvent('mouseout',  function() {this.removeClass('hover');});
		
		if (selectedKeyColumnValue && oTableConfig.keycolumn && oDataItem[oTableConfig.keycolumn] && selectedKeyColumnValue == oDataItem[oTableConfig.keycolumn]) oNormalRow.addClass('selected');
		
		if (oTableConfig.selectable) oNormalRow.addEvent('mousedown', function() {
			var curRow = $E('TR.selected', oTable);
			if (curRow) curRow.removeClass('selected');
			this.addClass('selected');
		});
		
		for (var z in oTableConfig.fields) {
			var oCell = new Element('td').injectInside(oNormalRow);
			
			if (oTableConfig.fields[z].prefix) oCell.appendText(oTableConfig.fields[z].prefix);
			
			if (oTableConfig.fields[z].icon) {
				if (oTableConfig.fields[z].icon[oDataItem[z]]) {
					var imageSrc = (oTableConfig.iconbase ? oTableConfig.iconbase : '') + oTableConfig.fields[z].icon[oDataItem[z]]; 
					new Element('img').setProperty('src', imageSrc).injectInside(oCell)
					oCell.addClass('centered');
				}
			} else {
				var str = oDataItem[z];
				oCell.setProperty('title', str);
				
				var maxStringLength = oTableConfig.fields[z].maxlength;
				if (maxStringLength && str.length > maxStringLength) var str = str.substr(0,maxStringLength-1) + '&#8230;';
				oCell.appendText(str);
				
				if (oTableConfig.fields[z].align == 'center') oCell.addClass('centered');
			}
			
			if (oTableConfig.fields[z].suffix) oCell.appendText(oTableConfig.fields[z].suffix);
		}

	});
	
	if (oData.more_results == 1 || oData.results_page > 1) {
		var oNaviRow = new Element('tr').addClass('navigation').injectInside(oTbody);

		var leftCell 		= new Element('td').injectInside(oNaviRow);
		if (totalSpanCounter - 2 > 0) var statusCell = new Element('td').addClass('statustext').setProperty('colspan', totalSpanCounter - 2).injectInside(oNaviRow);
		var rightCell		= new Element('td').injectInside(oNaviRow);
		
		if (oData.results_page > 1)  new Element('a').setProperty('href', '#').setStyles({'font': '14px Monospace', 'float': 'left', 'padding': '0 5px'}).setHTML('<').addEvent('click', function(e)  {new Event(e).stop(); oForm.page.value = oData.results_page.toInt() - 1; getDataAndBuildTable(oForm);}).injectInside(leftCell);
		if (oData.more_results == 1) new Element('a').setProperty('href', '#').setStyles({'font': '14px Monospace', 'float': 'right', 'padding': '0 5px'}).setHTML('>').addEvent('click', function(e) {new Event(e).stop(); oForm.page.value = oData.results_page.toInt() + 1; getDataAndBuildTable(oForm);}).injectInside(rightCell);
		if (statusCell) statusCell.setHTML('There are ' + oData.results_count + ' results. This is page ' + oData.results_page + ' of ' + Math.ceil(oData.results_count/oData.results_limit) + '.');
	}

	return oTable;
}


function setButtonWaitState(oButton, bState) {
	if (!oButton) return;
	
	var buttonImg = oButton.getElement('img');
	if (buttonImg) {
		if (bState) {
			buttonImg.alt = buttonImg.src
			buttonImg.src = '/img/ajaxload/button-load-indicator.gif';
		} else {
			buttonImg.src = buttonImg.alt;
		}
	}
	
	oButton.disabled = bState;
	
}

/* 
Random Tips
Pass in the id of a div containing the tips.

The DIV should have the class 'randomTipsDiv'!
Each tip must live inside a P tag
*/
function loadRandomTip(tipContainerId) {
	var tipContainerId = $(tipContainerId);
	if (tipContainerId) {
		var tipsElems = $ES('p', tipContainerId);
		var currentTipElem = $E('p.currentTip', tipContainerId);
	}
	
	if (!tipsElems || !tipsElems.length) return;
	
	if (currentTipElem) {
		currentTipElem.removeClass('currentTip');
		if (currentTipElem.getNext()) currentTipElem = currentTipElem.getNext();
		else currentTipElem = tipsElems[0];
	} else {
		var rand = $random(1, tipsElems.length) - 1;
		var currentTipElem = tipsElems[rand];
	}
	
	currentTipElem.setStyle('visibility', 'hidden').addClass('currentTip');
	
	tipContainerId.effect('height', {onComplete: function() {
		if (!Window.ie) currentTipElem.setStyles({'opacity': 0, 'visibility': 'visible'}).effect('opacity').start(1);
		else currentTipElem.setStyle('visibility', 'visible');
		
	}}).start(currentTipElem.offsetHeight + 20);
	
	return false;
}


function doEbaySearch(keywords) {
	var keywordsEscaped = keywords.replace(' ', '+');
	
//	location.href='http://rover.ebay.com/rover/1/711-53200-19255-0/1?type=3&campid=5335900664&toolid=10001&customid=&ext=' + keywordsEscaped + '&satitle=' + keywordsEscaped;
	
	location.href='http://rover.ebay.com/rover/1/711-53200-19255-0/1?type=4&campid=5335900664&toolid=10001&customid=&mpre=http%3A%2F%2Fcollectibles.search.ebay.com%2F' + keywordsEscaped + '_Machines_W0QQcatrefZC6QQdfspZ32QQfclZ3QQfposZQ5AIPQ2fPostalQQfromZR2QQfsooZ2QQfsopZ32QQftrtZ1QQftrvZ1QQsabfmtsZ1QQsacatZ13725QQsadisZ200QQsaobfmtsZinsifQQsargnZQ2d1QQsaslcZ2QQsbrftogZ1QQsofocusZbs';
	
	
}

