function log(msg) {
	if (!window['console']) return;
    window.console.log(msg);
}

function vof(x, thisObj) {
	if(typeof(x) == 'function')
		if(!thisObj)
			return x();
		else
			return x.call(thisObj);
	return x;
}

function accessor(thisObj, defaultValue) {
	var val = defaultValue;
	return function(v) {
		if(typeof(v) == 'undefined') return val;
		val = v;
		return thisObj;
	}
}

function isdef(x) {
	return typeof(x) != 'undefined';
}

var loadScript = (function() {
	
	function exists(parts) {
		var node = window;
		for(var i=0; i < parts.length; i++) {
			if(!node[parts[i]]) {
				return false;
			}
			node = node[parts[i]];
		}
		return true;
	}
	
	return (function(url, objSig, cb) {
	
		var parts = objSig.split('.');
		
		if(exists(parts)) {
			if(cb) cb();
			return;
		}
	
		var hd = document.getElementsByTagName('head')[0];
		var sc = document.createElement('script');
		var intr;
		
		sc.type = "text/javascript";
		sc.src = url;
		hd.appendChild(sc);
		
		intr = window.setInterval(function() {
			if(!exists(parts)) return;
			window.clearInterval(intr);
			if(cb) cb();
		}, 10);
	});
})();

var loadScripts = (function() {
							
	function doLoad(index, urls, objSigs, cb) {
		loadScript(urls[index], objSigs[index], function() {
			if(index==urls.length-1) {
				if(cb) cb();
				return;
			}
			doLoad(index+1, urls, objSigs, cb);
		});
	}
							
	return (function(urls, objSigs, cb) {
		doLoad(0, urls, objSigs, cb);
	});
})();

function UIFor(el) {
	var cache = {};
	UIFor = function(el) {
		if(!el) el = $('body').get()[0];
		var id = $.data(el);
		if(cache[id]) return cache[id];
		return (cache[id] = (new UI()).create(el)
				.init().draw());
	};
	return UIFor(el);
}

function UI() {
	this.create = function(domElement) {
    	var children = [], deathHandler;

		this.create = function() {};

        this.draw = function() {
			this.drawn = true;
            return this;
        };
		/* init() is designed to be called only once. Child class implementations of init
		 * will be called once and then re-assigned such that subsequent calls to init
		 * will do nothing. */
        this.init = function() {
			this.init = function() { return this; };
            return this;
        };
        this.de = function() {
        	return domElement;
        };
        this.dispose = function() {};
        this.ce = function() {
        	return this.de();
        };
        this.addChild = function(childObject) {
        	var env = this;
        	if(childObject instanceof Array) {
        		return childObject.each(function(o) {
        			env.addChild(o);
        		});
        	}
            childObject.parent = (function(env) {
            	return function() {
            		return env;
            	};
            })(this);
            childObject.root = function() {
            	var out = this.parent();
            	while(true) {
            		if(!out['parent']) return out;
            		out = out.parent();
            	}
            };
            children[children.length] = childObject;

            this.ce().appendChild(childObject.de());
            return childObject;
        };
        function unb(el) {
        	$(el).unbind();
        	for(var i=0; i < el.childNodes.length; i++) {
        		if(el.childNodes[i].nodeName == '#text')
        			continue;
        		unb(el.childNodes[i]);
        	}
        	return el;
        }

        this.removeChild = function(childObject) {
			childObject = vof(childObject, this);
        	for(var i=0; i < children.length; i++) {
        		if(children[i] == childObject) {
        			this.ce().removeChild(unb(children[i].preDeath().de()));
        			children[i].dispose();
        			children.splice(i, 1);
        		}
        	}
        };
        this.preDeath = function(fn) {
        	if(typeof(fn) == 'undefined') {
        		if(deathHandler) deathHandler();
        		return this;
        	}
        	deathHandler = fn;
        	return this;
        };
        this.indexOf = function(childObject) {
        	if(childObject == this) return -1;
        	for(var i=0; i < children.length; i++)
        		if(children[i] == childObject) return i;
        	return -1;
        };
        this.removeChildren = function(fn) {
        	var more = function() {};
        	while(true) {
	        	try {
	        		var env = this;
	        		this.eachChild(function(ch) {
	        			if(fn && fn(ch) === false) return;
	        			env.removeChild(ch);
	        			throw new more();
	        		});
	        		break;
	        	} catch(e) {
	        		if(!(e instanceof more)) throw e;
	        	}
        	}
        };
        this.eachChild = function(fn) {
        	for(var i=0; i < children.length; i++)
        		if(fn(children[i], i) === false) break;
        };
		this.children = function(a) {
			if(!isdefined(a))
				return children;
			children = a;
			return this;
		};
        this.numChildren = function() {
        	return children.length;
        };
        this.firstChild = function(fn) {
        	if(children.length == 0) return null;
        	if(fn) fn.call(children[0]);
        	return children[0];
        };
        this.childAt = function(index) {
        	return children[index];
        };
        this.redraw = function() { 
			if(!this.drawn) return;
			this.draw();
            for(var i=0; i < children.length; i++)
            	children[i].redraw();
            return this;
        };
        this.op = function(fn) {
        	if(fn) fn.call(this);
        	return this;
        };
        return this;
	};
}

var Canv = (function(Canv) {
	Canv.prototype = new UI();
	return Canv;
})(function() {
	this.create = (function(create) {
		return function(initFn, drawFn) {
			create.apply(this, [document.createElement('div')]);
			this.init = (function(init) {
				return function() {
					this.de().style.position = 'absolute';
					if(initFn) initFn.call(this);
					return init.call(this);
				};
			})(this.init);
			this.draw = (function(sup) {
				return function() {
					if(drawFn) drawFn.call(this);
					return sup.call(this);
				};
			})(this.draw);
			return this;
	   };
	})(this.create);
});

var Canvas = function(initFn, drawFn) {
	return new Canv().create(initFn, drawFn);
};

var Layer = (function() {
	var bseDepth = 800, depth = bseDepth, layer = 0, stack = [];
	return function(initFn, drawFn) {
		var resize;
		
		function firstModal() {
			var firstVisible;
			for(var i = 0; i < stack.length; i++) {
				if((!firstVisible) && stack[stack.length-1-i].overlay()) {
					$(stack[stack.length-1-i].overlay()).css('visibility', 'visible');
					firstVisible = true;
					continue;
				}
				if(stack[stack.length-i-1].overlay())
					$(stack[stack.length-i-1].overlay()).css('visibility', 'hidden');
			}
			return null;
		}

		return Canvas(function() {
			var env = this;
			layer++;
			$(this.de()).css('z-index', depth+(2*layer));
			if(this.modal()) {
				$('body').get()[0].appendChild((function(de, o) {
					o.overlay(de);
					$(de)
					.addClass('overlay')
					.css('z-index', (depth+(2*layer))-1)
					.css('position', 'absolute')
					.css('left', 0).css('top', 0);
					return de;
				})(document.createElement('div'), this));
			}
			firstModal();
			
			resize = function() {
				env.draw();
			};
			$(window).resize(resize)
			.scroll(resize);
			
			if(initFn) initFn.call(this);
		}, function() {
			if(this.overlay()) {
				$(this.overlay()).width($(window).width())
				.height($(window).height())
				.css('left', $(window).scrollLeft())
				.css('top', $(window).scrollTop());
			}

			if(drawFn) drawFn.call(this);
		}).op(function() {
			this.modal = accessor(this, true);
			this.overlay = accessor(this);
			this.dispose = function() {
				layer--;
				if(this.modal()) $('body').get()[0].removeChild(this.overlay());
				stack.splice(index.call(this), 1);
				$(window).unbind('resize', resize).unbind('scroll', resize);
				function index() {
					for(var i=0; i < stack.length; i++) {
						if(stack[i] == this) return i;
					}
				}
				firstModal();
			};
			this.isTopDialog = function() {
				return stack[stack.length-1] == this;	
			};
			stack[stack.length] = this;
			index = stack.length-1;
		});
	};
})();

function DialogShadowResize() {
	var dialog = $('.dialog');
	var height = dialog.height();
	var width = dialog.width();

	dialog.find('.shadow-t, .shadow-b').css('width',width);
	dialog.find('.shadow-r, .shadow-l').css('height',height);
	dialog.find('.shadow-r, .shadow-tr, .shadow-br').css('left',width);
	dialog.find('.shadow-b, .shadow-bl, .shadow-br').css('top',height)
}

var Dialog = function(initFn, drawFn) {
	var titleBar, contentCntr, title, width, height, bse, closable = true, dc, 
		firstDraw = true, ctOverflow = 'auto';
	
	function makeBase() {
		var e={}, w = 8;
		$.each(['t', 'tr', 'r', 'b', 'bl', 'l', 'br', 'tl'], function() {
			bse.appendChild((e[this]=document.createElement('div')));
			$(e[this]).css('position', 'absolute')
			.addClass('shadow')
			.addClass('shadow-'+this)
			.css('line-height', '0px');
		});
		makeBase = function() { 
			$(e.t)
			.css('left', 0)
			.css('top', -w)
			.width(this.de().offsetWidth)
			.height(w);
			
			$(e.tr)
			.css('left', this.de().offsetWidth)
			.css('top', -w).width(w).height(w);
			
			$(e.r)
			.css('left', this.de().offsetWidth)
			.css('top', 0)
			.width(w)
			.height(this.de().offsetHeight);
			
			$(e.b)
			.css('top', this.de().offsetHeight)
			.css('left', 0)
			.height(w)
			.width(this.de().offsetWidth);
			
			$(e.bl)
			.css('top', this.de().offsetHeight)
			.css('left', -w).width(w).height(w);
			
			$(e.l)
			.css('top', 0)
			.css('left', -w)
			.width(w).height(this.de().offsetHeight);
			
			$(e.br)
			.css('top', this.de().offsetHeight)
			.css('left', this.de().offsetWidth)
			.width(w).height(w);
			
			$(e.tl)
			.css('top', -w)
			.css('left', -w)
			.width(w).height(w);
		};
		makeBase.call(this);
	}
	
	return Layer(
		function() {
			var env = this, i = 0;
			$(contentCntr).css('overflow', ctOverflow);
			$(this.de()).addClass('dialog');
			if(dc) for(i=0; i < dc.length; i++) {
				$(this.de()).addClass(dc[i]);
			}
			$(titleBar).html(title||(closable ? '&nbsp;' : ''));
			if(!title) { 
				$(titleBar).addClass('empty');
			}
			if(closable)
				titleBar.appendChild((function(a) {
					$(a).attr('href', '#')
					.addClass('xlink')
					.text('close x')
					.click(function(e) {
						env.parent().removeChild(env);
						e.preventDefault();
					});
					return a;
				})(document.createElement('a')));
				
			if(isdef(width)) {
				$(this.de()).width(width);
				$(contentCntr).width(this.de().offsetWidth);
			}
			if(isdef(height)) {
				$(this.de()).height(height);
				$(contentCntr).height(this.de().offsetHeight - titleBar.offsetHeight);
			}
			
			$(this.de()).css('top',0).css('left',0);

			if(initFn) initFn.call(this);
		},
		function() {
			/* prevents parts of the dialog from being unaccessible esp. w/ low screen resolutions */
			if((!firstDraw) && ((this.de().offsetHeight > $(window).height()) 
					|| (this.de().offsetWidth > $(window).width()))) {
				return;
			}
			if(!firstDraw) return;
			firstDraw = false;
			if(drawFn) { 
				drawFn.call(this);
			} else { 
				if(width) $(this.de()).width(width);
				if(height) $(this.de()).height(height);
				$(this.de())
				.css('left', $(window).scrollLeft() + (($(window).width()/2) - (this.de().offsetWidth/2)))
				.css('top', $(window).scrollTop() + (($(window).height()/2) - (this.de().offsetHeight/2)));
			}
			makeBase.call(this);
		}
	).op(function() {

		var lyr = this, ct;

		this.de().appendChild((bse = document.createElement('div')));
		$(bse).css('position', 'absolute');
		
		titleBar = document.createElement('div');
		$(titleBar).addClass('title')
			.css('position', 'relative')
			.css('z-index', 2);
		lyr.de().appendChild(titleBar);
		
		contentCntr = document.createElement('div');
		$(contentCntr).css('position', 'relative')
			.css('z-index', 1).css('overflow', 'auto');
		lyr.de().appendChild(contentCntr);
		contentCntr.appendChild((function(de, s) {
			s.ce = function() { return de; }
			$(de).addClass('content');
			return de;
		})(document.createElement('div'), this));

		this.dispose = (function(o, sup) {
			var isd = false;
			o.isDisposed = function() {
				return isd;
			}
			return function() {
				sup.call(this);
				isd = true;
				if(this.onDispose())
					this.onDispose()();
			};
		})(this, this.dispose);

		this.onDispose = accessor(this);

		this.closable = function(x) {
			closable = x;
			return this;
		};
		
		this.draggable = function(x) {
			$(titleBar).css('cursor','move');
			$(this.de()).draggable();
		};
		
		this.title = function(x) {
			title = x;
			return this;
		};
		
		this.width = function(w) {
			width = w;
			return this;
		};
		
		this.height = function(h) {
			height = h;
			return this;
		};
		
		/* controls the overflow property of the content 
		 * container */
		this.contentOverflow = function(o) {
			ctOverflow = o;
			return this;
		};
		
		/* adds the given class to the main .dialog element */
		this.addClass = function(c) {
			if(!dc) dc = [];
			dc[dc.length] = c;
			return this;
		};
	});
};

var Cookie = {
	get: function(name) {
		if (document.cookie.length > 0) {
			var start = document.cookie.indexOf(name + "=");
			if (start==-1 || name=="")
				return null; 
			var end = document.cookie.indexOf(";", start);
			if (end==-1)
				end = document.cookie.length;
			return unescape(document.cookie.substring(start+name.length+1, end));
		}
		return null;
	},
	
	set: function(name, value, expire_days) {
		var domain = COOKIE_DOMAIN;
		var c_expires = "";
		var c_domain = "";
		if (isdef(expire_days)) {
			var date = new Date();
			date.setTime(date.getTime() + (expire_days*24*60*60*1000));
			var c_expires = "; expires=" + date.toGMTString();
		}
		if (domain) {
			var c_domain = "; domain=" + domain;
		}
		document.cookie = name + "=" + escape(value) + c_expires + "; path=/" + c_domain;
	},
	
	remove: function(name) {
		Cookie.set(name, "", -1);
	}
};

var _dgx_cache = {};

function showDialog(params) {
	var i, classes, dgx = Dialog(
		function() {
			if (isdef(params.htmlID)) {
				if (!isdef(_dgx_cache[params.htmlID])) {
					_dgx_cache[params.htmlID] = $('#'+params.htmlID);
					_dgx_cache[params.htmlID].parent()[0].removeChild(_dgx_cache[params.htmlID][0]);
				}
				$(this.ce())[0].appendChild(_dgx_cache[params.htmlID][0]);
				_dgx_cache[params.htmlID].show();
			}
			else {
				$(this.ce()).html(params.html);
			}
		},
		function() {
			if (params.centered) { 
				$(this.de())
				.css('left', $(window).scrollLeft() + (($(window).width()/2) - (this.de().offsetWidth/2)))
				.css('top', $(window).scrollTop() + (($(window).height()/2) - (this.de().offsetHeight/2)));
			}
			else {
				var top = isdef(params.top) ? params.top : 72;
				var left = isdef(params.left) ? params.left : ($(window).width()/2) - (this.de().offsetWidth/2);
				$(this.de())
				.css('left', $(window).scrollLeft() + left)
				.css('top', $(window).scrollTop() + top);
			}
		}
	);
	
	if(params.onDispose) {
		dgx.onDispose(params.onDispose);
	}
	
	/* classes can be a string or an array of class names to be applied 
	 * to the dialog. */
	if(isdef(params.classes)) {
		if(typeof(params.classes) == 'string')
			classes = [params.classes];
		for(i=0; i < classes.length; i++) {
			dgx.addClass(classes[i]);
		}
	}
	
	if(isdef(params.width)) {
		dgx.width(params.width);
	}
	
	if(isdef(params.height)) {
		dgx.height(params.height);
	}
	
	if (isdef(params.modal)) {
		dgx.modal(params.modal);
	}
	else {
		dgx.modal(true);
	}
	
	if(isdef(params.closable)) {
		dgx.closable(params.closable);
	}
	
	if (isdef(params.title)) {
		dgx.title(params.title);
	}
	
	if (isdef(params.draggable)) {
		dgx.draggable(params.draggable);
	}
	
	if(isdef(params.contentOverflow)) {
		dgx.contentOverflow(params.contentOverflow);
	}
	
	return UIFor().addChild(dgx).init().draw();
}

function hideDialog(dgx) {
	if (dgx !== null) {
		dgx.parent().removeChild(dgx);
	}
}

$(document).ready(function() {
	// ie <a><button/></a> workaround
	//var is_ie7 = jQuery.browser.msie && parseInt(jQuery.browser.version.substr(0,1)) <= 7;
	if (jQuery.browser.msie) {
		$('button.button').click(function(e) {
			if ($(this).attr('onclick') === null) {
				var parent = $(this).parent();
				if (parent.attr('onclick') === null) {
					var url = parent.attr('href');
					if (isdef(url)) {
						e.preventDefault();
						e.stopPropagation();
						go(url);
					}
				}
				else {
					parent.click();
				}
			}
		});
	}
	// this fixes a UI problem with underlines over buttons
	$('a button.button').parent().addClass('no-ul');
	
	// hookup signup link
	$('#SigninLink').click((function() {
		return function(e) {
			e.preventDefault();
			var dgx = showDialog({title:'Sign In or Register', htmlID:'LoginCntr', width:600});
			$(dgx.ce()).find('[name=login]').focus();
		};
	})());
	if(window['pageCtl']) pageCtl();
});

// extend jquery to clear a specified form, ie: $('form').clearForm()
$.fn.clearForm = function() {
  return this.each(function() {
    var type = this.type, tag = this.tagName.toLowerCase();
    if (tag == 'form')
      return $(':input',this).clearForm();
    if (type == 'text' || type == 'password' || tag == 'textarea')
      this.value = '';
    else if (type == 'checkbox' || type == 'radio')
      this.checked = false;
    else if (tag == 'select')
      this.selectedIndex = -1;
  });
};

// extend jquery to set cursor positions in a textarea
$.fn.setCursorPosition = function(pos) {
	if ($(this).get(0).setSelectionRange) {
		$(this).get(0).setSelectionRange(pos, pos);
	}
	else if ($(this).get(0).createTextRange) {
		var range = $(this).get(0).createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
}

function showElementId(id) {
	$(id).show();
}

function hideElementId(id) {
	$(id).hide();
}

function toggleDisplayElementId(id) {
	var el = $(id);
	
	if (el.css('display') == 'none') {
		el.show();
	}
	else {
		el.hide();
	}
}

function go(url) {
	document.location.href = url;
	return false;
}

function login() {
	if (!isdef(islog)) {
		showDialog({html:'<div class="section">login() not initialized correctly</div>', title:'ERROR'});
		return false;
	}
	else if (islog == 1) {
		return true;
	}
	$('#SigninLink').click();
	return false;
}

var SearchBar = {
	default_text: "Enter image keyword(s)",
	is_reset: false,
	
	activate: function() {
		$("#search_keyword").css("color", "#ccc").attr("value", this.default_text);
	},
	focus: function() {
		var st = $("#search_keyword");
		var kw = st.val();
		st.setCursorPosition(kw.length);
		if (kw == this.default_text) {
			st.attr("value","").css("color","#000");
		}
	},
	blur: function() {
		if ($("#search_keyword").val() == "") {
			$("#search_keyword").css("color","#ccc").attr("value", this.default_text);
		}
	},
	submit: function() {
		var st = $("#search_keyword");
		if (st.val() == this.default_text) {
			st.attr('value','');
			//return false;
		}
		return true;
	},
	reset: function() {
		$('#advsearch_text').removeClass('confirm');
		$('#advanced_search_icon').removeClass('advanced-search-on').addClass('advanced-search');
		$('#formsearch :input').each(function() {
		    var type = this.type, tag = this.tagName.toLowerCase();
			if (type == 'text' || type == 'password' || tag == 'textarea')
				this.value = '';
			else if (type == 'checkbox' || type == 'radio')
				this.checked = false;
			else if (tag == 'select')
				this.selectedIndex = 0;
		});
		$('#formsearch label').each(function() {
			$(this).removeClass('custom');
		});
		
		this.activate();
		this.is_reset = true;
	},
	toggleAdvanced: function(is_advanced) {
		is_advanced = isdef(is_advanced) && is_advanced && !this.is_reset;
		var el = $('#advsearch_toggle');
		el.find('button').toggleClass('advanced-search-hide','advanced-search');
		$('#advsearch_text').html(($('#advsearch_text').html().substring(0,4)!='hide'?'hide advanced search':(is_advanced?'advanced search is ON':'advanced search')));
		$('#advsearch').toggleClass('visible','hidden');
		$('#search_bar').toggleClass('less_wide');
		
		if ($('#advsearch').hasClass('visible')) {
			$('body').append('<div id="advsearch_dimmer" class="overlay" style="position:absolute; top:0; left:0; width:100%; height:100%; z-index:100;"></div>');
		}
		else {
			$('#advsearch_dimmer').remove();
		}
		return false;
	}
}

String.prototype.trim = function(pattern) {
	return this.lTrim(pattern).rTrim(pattern);
}
String.prototype.lTrim = function(pattern) {
	if(pattern == null) {
		pattern = /\s/;
	}
	else if(typeof(pattern).toString().toLowerCase() == 'string') {
		pattern = new RegExp(pattern);
	}
	var i = 0;
	while(i < this.length-1 && pattern.test(this.charAt(i))) i++;
	return this.substring(i,this.length);
}
String.prototype.rTrim = function(pattern) {
	if(pattern == null) {
		pattern = /\s/;
	} else if(typeof(pattern).toString().toLowerCase() == 'string') {
		pattern = new RegExp(pattern);
	}
	var i=this.length-1;
	while(i >= 0 && pattern.test(this.charAt(i))) i--;
	return this.substring(0,i+1);
}
// thanks IE6
Array.prototype.indexOf = function() {
	for(var i=0; i < this.length; i++) {
		if(this[i] == arguments[0]) return i;
	}
	return -1;
}

function newsletter_signup() {
	email = document.getElementById('newsletter_email').value
	var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
	if(reg.test(email) == false) {
	 	msgBox = document.getElementById('newsletter_error')
	 	msgBox.innerHTML = 'Invalid Email Format';
	 	msgBox.style.visibility = 'visible'
		return false;
	}
	jQuery.ajax({ 'url': "/newsletter/signup/", 
					'data': {'email':email,'inline':'1'},
					'type': 'POST',
					'dataType': 'test', 
					'success': function(response){
						if ( response==1 ) {
							msgBox = document.getElementById('newsletter_error')
							msgBox.innerHTML = 'Thank You!';
							msgBox.style.visibility = 'visible'
						}
      				}
      			});
	return true;
}

function set_placeholder_text(objref, text, clear) {
	if ( objref.value == text && clear ) {
		objref.value = ''
	} else if ( objref.value == '' && !clear ) {
		objref.value = text
	}
}
