/* -*- mode: c; tab-width: 2; c-tab-always-indent: t; c-basic-offset: 2; comment-column: 0 -*- */
/* global platform js */

/* Add "hover" class to elements on with class name "hvr" in IE6 */
/*@cc_on
@if (@_jscript_version < 5.7)
(function(){
  var rx = /^hvr(?:\s|$)|\ska-hvr(?:\s|$)/;
	function onMouseHover() {
		var e = event;
		for (var el = e.srcElement; el; el = el.parentNode){
			if (!rx.test(el.className))
				continue;
			if (e.type == 'mouseover')
				el.className += ' ka-hover';
			else
				el.className = el.className.replace(/^ka-hover(?:\s|$)|\ska-hover(?:\s|$)/, ' ');
		}
	}

	document.attachEvent('onmouseout', onMouseHover);
	document.attachEvent('onmouseover', onMouseHover);
})();
@end @*/


/*@cc_on try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {} @*/

if (!Function.prototype.bind){
	Function.prototype.bind = function(context){
		var oArgs, fnMethod = this, slice = Array.prototype.slice;
		if (arguments.length > 1){
			oArgs = slice.call(arguments, 1);
		}
		return function(){
			return oArgs ?
				fnMethod.apply(context, slice.call(arguments, 0).concat(oArgs)) :
				fnMethod.apply(context, arguments);
		}
	}
};

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisp*/)
  {
    var i = 0,
        len = this.length >> 0;

    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (; i < len; i++)
    {
      if (i in this &&
          fun.call(thisp, this[i], i, this))
        return true;
    }

    return false;
  };
}

if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res[i] = fun.call(thisp, this[i], i, this);
    }

    return res;
  };
}

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  };
}

(function() {
	/* Extending the jQuery event with a basic predicate for leting us
		 know what key was pressed.  */
	var keymap = {
		Backspace: 8,
		Tab: 9,
		Delete: 46,
		Enter: 13,
		Escape: 27,
		Left: 37,
		Up: 38,
		Right: 39,
		Down: 40,
		Comma: 44,
		Space: 32
	};

	jQuery.Event.prototype.isKeyPressed = function(key) {
		if (key == 'Down')
			return this.keyCode == keymap[key];
		return (this.keyCode || this.charCode) == keymap[key];
	};

	jQuery.Event.prototype.isAnyKeyPressed = function() {
		return Array.prototype.some.call(arguments, this.isKeyPressed, this);
	};

	jQuery.Event.prototype.isAlphaKey = function() {
		var k = +(this.keyCode || this.charCode);
		return (k > 64 && k < 91) || (k > 96 &&  k < 123);
	};

	jQuery.Event.prototype.isNumericKey = function() {
		var k = +(this.keyCode || this.charCode);
		/* a number 0-9 was pressed */
		return (k > 47 && k < 58);
	};

	jQuery.Event.prototype.isNumericHexKey = function() {
		var k = (this.keyCode || this.charCode);
		/* an `#' or a to f or A to F was pressed */
		return this.isNumericKey() || k == 35 || (k > 96 && k < 103) || (k > 64 && k < 71);
	};

	jQuery.Event.prototype.isAlphaNumericKey = function() {
		return this.isNumericKey() || this.isAlphaKey();
	};

})();

(function(){
	function handle(e, $t, actions, test, context) {
	for (var action in actions)
		if (test($t, action)){
			actions[action](context, e, $t);
			return true;
		}
		return false;
	}

	jQuery.Event.prototype.handleTargetWithActionsByTest = function(actions, test, context) {
		return handle(this, $j(this.target), actions, test, context);
	}
})();

jQuery.Event.prototype.handleTargetWithActionClasses = function(actions, context) {
	return this.handleTargetWithActionsByTest(actions, function($t, cls) {
		return $t.hasClass(cls) || $t.parents('.'+cls+':first').length > 0;
	}, context);
};

/* punny jQuery */
jQuery.event.props.push('layerX', 'layerY', 'offsetX', 'offsetY');

/* Overwriting the default jquery serializeArray, coz it ignores named
	 submit buttons. As our server side guys expect a lot of forms to
	 work with named submits we can't just ignore this. When jQuery guys
	 fix this then we should remove this patch. On a side not jquery's
	 form serialization gets expotentionally slower as the form size
	 grows. Where yukus old form serialization grew leniary.
 */
jQuery.fn.serializeArray = function(){
	return this.map(function(){
		return this.elements ? jQuery.makeArray(this.elements) : this;
	})
	.filter(function(){
		return this.name && !this.disabled &&
			(this.checked || /select|textarea/i.test(this.nodeName) ||
			 /text|hidden|submit|password/i.test(this.type));
	})
	.map(function(i, elem){
		var val = jQuery(this).val();
		return val == null ? null :
			jQuery.isArray(val) ?
			jQuery.map(val, function(val, i){
				return {name: elem.name, value: val};
			}) :
			{name: elem.name, value: val};
		}).get();
};

// move jQuery object to $j namespace, and defaut $ to usual
var $j = jQuery.noConflict(), $ = function(x){return document.getElementById(x);};

(function(){
	var cls = ' ka-js ka-loading-page';
	var bwr = jQuery.browser;
	for (var key in bwr) {
		if (bwr[key] !== true)
			continue;
		cls += ' ka-'+key+' ka-'+key+'-'+bwr.version.replace(/\./g, '-');
	}
	document.documentElement.className += cls;
})();

$j.fn.get$J = function(){
	/* Return the jquery object from any element. Needed when for when
		 passing $elements across frames and you want to create $elements
		 in the frame from wich the $element came. Not sure if jquery
		 provides such thing already. */
	return $j;
};

Yuku = {
	Paths: {
		SKINS: '/skins/pro/',
		UPLOADIFY: window.gs.staticServer + '/common/bypass/images/uploadify.swf'
	},

	Info: {

		 User: {
		/*
		 These are printed by server-side in the <head> after the inclusion of base.js
			NAME: 'Mauvis'
			PHOTO: "static.something/loaction/to/image",
			DEFAULT_PHOTO: "static.something/loaction/to/image"
			FRIENDS_LISTS: [{title: string, id: 1}, ...]
		*/
		}

	},

	Preferences: {
		UI: {
			roundedCorners: false
		},
		Notice: { /* used by Yuku.Util.showNotice */
			displayDuration: 1 /* in seconds */
		}
	},

	Util: {
		String: {
			TPLS: {},
			replaceFromDict: function(str, dict) {
				return str.replace(/#{([^}]+)}/g, function(m, k) { return k in dict ? dict[k] : m; });
			},
			deserialize: function(str) {
				var ret = {};
				var search = str.slice(str.indexOf('?')+1);
				if (search){
					for (var pairs = search.split('&'), i = 0, l = pairs.length, pair; i < l; i++) {
						pair = pairs[i].split('=');
						key = decodeURIComponent(pair[0]);
						val = decodeURIComponent(pair[1]);
						if (key in ret){
							if (!(ret[key] instanceof Array)){
								ret[key] = [ret[key]];
							}
							ret[key].push(val);
						} else {
							ret[key] = val;
						}
					}
				}
				return ret;
			},

			camelize: function(str) {
				return str.replace(/[-_]\w/g, function(x){return x.charAt(1).toUpperCase()});
			}
		},

		Math: {
			limit: function(n, nMin, nMax) {
				return n < nMin ? nMin : (n > nMax ? nMax : n);
			}
		},

		Dom: {},

		pageScroll: function(){
			var win = document.documentElement, body = document.body;
			return {top: Math.max(win.scrollTop, body.scrollTop),
							left:Math.max(win.scrollLeft, body.scrollLeft)};
		},

		normalize_color: function(v){
			if (v === null || v === undefined)
				return null;
			if (v.constructor == Number)
				return ("000000" + v).toString(16).slice(-6);
			else if (v.charAt(0) == '#')
				return v.slice(1);
			else if (v.constructor == String){
				if (v.indexOf('rgb(') != -1){
					v = v.match(/\d+/g);
					if (v)
						return ("000000"+ (v[0] << 16 | v[1] << 8 | v[2] << 0).toString(16)).slice(-6);
				}
				else if (v == 'transparent')
					return '';
				return v;
			}
			return null;
		},

		changeTheme: function(filename, title){
			title = title || 'skin: ' + filename;

			// if active style is current style return
			if ( title == $('ka-currentSkin').title ){
				return;
			}

			$j('#ka-currentSkin')
			.attr('title', title)
			.attr('disabled',true)
			.attr('href', Yuku.Paths.SKINS + filename +'/skin.css')
		  .attr('disabled', false);
		},

		Cookie: {
			get: function(sName){
				for (var aCookies = document.cookie.split('; '), i = aCookies.length, aPair; i--;){
					aPair = aCookies[i].split('=');
					if (aPair[0] == sName){
						return decodeURIComponent(aPair[1]);
					}
				}
				return null;
			},

			set: function(sName, sValue, iHours){
				if (!iHours){
					iHours = 1000000; // 100+ years
				}
				var oDate = new Date();
				oDate.setTime( +oDate + (iHours * 3600 * 1000));
				document.cookie = sName + '=' + encodeURIComponent(sValue)
					+ '; expires=' + oDate.toGMTString() + '; path=/;';
			},

			del: function(sName) {
				yut.Cookie.set(sName, '', -1);
			}
		},

		removeListItem: function($li){
			if (!$li.length){
				return;
			}
			$li.fadeOut('slow', function() {
/* wierd IE6 bug with resizing of with section action position messing up,
	 this is an ugly hack, but I don't have another way of doing it right now.
*/
/*@cc_on
	@if (@_jscript_version < 5.8)
				var $col = $li.parents('.ka-section:first').find('.ka-section-actions').hide();
				setTimeout(function() {
					$col.show();
				}, 1);
@end @*/
				if ($li.siblings().length){
					$li.remove();
				} else {
					$li.parent().replaceWith($j('<p>No items</p>'));
				}
			});
		},

		getItemLists: function($where) {
			var $ul = $where.find('ul.ka-item-list');
			if (!$ul.length) {
				$ul = $j('<ul class="ka-item-list"></ul>');
				var $p, $ps = $where.find('p');
				for (var l = $ps.length; l--; ){
					$p = $j($ps[l]);
					if ($j($p).text().toLowerCase() == 'no items'){
						$p.replaceWith($ul);
						break;
					}
				}
				if (l == -1) {
					$where.append($ul);
				}
			}
			return $ul;
		},

		addListItem: function($list, itemcontent) {
			var $item;
			if (itemcontent.constructor == String)
				$item = $j('<li style="display: none">'+itemcontent+'</li>').appendTo($list);
			else
				$item = $j('<li style="display: none"></li>').append(itemcontent).appendTo($list);
			$item.fadeIn();
			return $item;
		}
	},

	Plugins: {
		Carousel: {
			create: function(vContainer, oArgs){
				var $elContainer = $j(vContainer);
				var $holder = $elContainer.find('div.ka-carousel-container:first');
				var $elList = $elContainer.find('ul:first');
				var $oItemList;

				var scroll_size, scroll_step, scroll_width;

				function set_scroll_vars(){
					$oItemList = $elList.find('li');
					if ($oItemList.length)
						$elList.width($oItemList[0].offsetWidth * $oItemList.length);
					else
						$elList.width(0);
					scroll_size = $holder[0].scrollWidth;
					scroll_step = parseInt($holder.css('width'));
					scroll_width = $holder[0].offsetWidth;
				}

				set_scroll_vars();

				var $btns = $elContainer.find('button');
				oArgs = $j.extend(oArgs, {
					leftButton: $btns[0],
					rightButton: $btns[1]
				});

				var elLButton = oArgs.leftButton;
				var elRButton = oArgs.rightButton;

				function setScrollState(){
					var scroll_left = $holder[0].scrollLeft;
					$j(elLButton).toggleClass('ka-inactive', scroll_left == 0);
					$j(elRButton).toggleClass('ka-inactive', scroll_left + scroll_width >= scroll_size);
				}

				function scroll(by){
					$holder.animate({scrollLeft: Math.min($holder[0].scrollLeft + by * scroll_step, scroll_size)},
													setScrollState);
				}

				function handleScrollButton(e){
					var bLeft = (this == elLButton);
					scroll(bLeft ? -1 : 1);
					this.blur();
					return false;
				}

				$j(elLButton).click(handleScrollButton);
				$j(elRButton).click(handleScrollButton);
				setScrollState();
				return {reshape: set_scroll_vars}
			}
		}
	},

	Platform: {
		globalMethodNames: ['checkUserSettings', 'clearSearch'],

		checkUserSettings: function(){
			var y = Yuku, ypr = y.Preferences;

			// first check if rounded corners are enabled
			if (ypr.UI.roundedCorners){

				//add a inner wrapper around all div elements with class .rounded
				//console.profile('rounded');
				$j('div.ka-rounded').each(function(i,o){
					//console.log('rounding', i);
					var $e = $j(o),
					id = $e.attr('id'),
					label = id !== ''
						? ' id="' + id + '-inner" class="ka-inner"'
						: '';
					$e.wrapInner('<div' + label + '></div>');
				});
				//console.profileEnd();
			}
		},

		clearSearch: function(){
			$j('input.ka-search-query').one('focus', function() {
				this.value = '';
			});
		}
	},

	Page: {}
};
var y = Yuku, ypr = y.Preferences, ypl = y.Platform, yut = y.Util, yusr = Yuku.Info.User;

yut.withDelegateOp = function(opName, fn) {
	return function() {
		var del = this.delegate;
		var	op = 'can'+opName;

		if (del && (op in del) && !del[op](this))
			return false;

		var success = fn.apply(this, arguments);

		if (del) {
			if (success !== false) {
				op = 'did'+opName;
				if (op in del)
					del[op](this);
			}
			else {
				op = opName+'DidFail';
				if (op in del)
					del[op](this);
			}
		}
		return success;
	}
};

yut.make_clearable = function($el, defaultValue, className, onclear) {
	if (!defaultValue)
		defaultValue = '';
	if (!className)
		className = '';

	var $span = $j('<span class="ka-clearable ka-clearable-'+$el.attr('tagName').toLowerCase()+' '+className+'"></span>');
	if ($el.parent().length)
		$span.insertBefore($el);
	$el.appendTo($span);

	$el.attr('value', defaultValue);

	function change(){
		$span.toggleClass('ka-has-value', $el.attr('value') != '');
	}
	change();

	$el.bind('keyup', change).bind('change', change);
	yut.make_$button('clear', 'clear').appendTo($span).click(function(){
/* 		$el.attr('value', defaultValue).trigger('change'); */
			$el.attr('value', '').trigger('change');
		if (onclear)
			onclear($span);
		}).bind('mousedown', function(e){e.preventDefault(); return false;}).attr('UNSELECTABLE', true);
	return $span;
};

yut.make_clearable$Input = function(defaultValue, className, onclear) {
	return yut.make_clearable($j('<input>'), defaultValue, className, onclear);
};

yut.make_clearable$Textarea = function(defaultValue, className, onclear) {
	return yut.make_clearable($j('<textarea>'), defaultValue, className, onclear);
};

yut.make_$button = function(title, className) {
	if (!title) title = '';
	return $j('<button UNSELECTABLE type="button" title="'+title+'" class="'+(className || '')+'"><span>'+title+'<span></button>');
};

(function(){
	function rangeLengthWithEndPoint(el, endpoint){
		if (document.selection && document.selection.createRange){
			var rng = document.selection.createRange().duplicate();
      var rng2 = document.body.createTextRange();
      rng2.moveToElementText(el);
			rng2.setEndPoint(endpoint, rng);
			return rng2.text.length;
		}
		return -1;
	};

	yut.getSelectionStart = function(el){
		if (typeof el.selectionStart != 'undefined')
			return el.selectionStart;
		return rangeLengthWithEndPoint(el, 'EndToStart');
	};

	yut.getSelectionEnd = function(el){
		if (typeof el.selectionEnd != 'undefined')
			return el.selectionEnd;
		return rangeLengthWithEndPoint(el, 'StartToEnd');
	};

	yut.setSelectionStart = function(el, offset){
		if (typeof el.selectionStart != 'undefined')
			el.selectionStart = offset;
		else if (document.selection && document.selection.createRange){
			var rng = document.selection.createRange();
      var rng2 = document.body.createTextRange();
      rng2.moveToElementText(el);
			rng2.setEndPoint('EndToStart', rng);
			rng2.moveStart('character', offset);
			rng2.select();
		}
	};

	yut.setSelectionEnd = function(el, offset){
		if (typeof el.selectionEnd != 'undefined')
			el.selectionEnd = offset;
		else if (document.selection && document.selection.createRange) {
			var rng = document.selection.createRange();
      var rng2 = document.body.createTextRange();
      rng2.moveToElementText(el);
			rng2.moveStart('character', offset);
			rng.setEndPoint('EndToStart', rng2);
			rng.select();
		}
	};
})();

(function(counter){
	/* yut.String.unique generates a strig guarantied not to be the same to
		 a string has been or will be generated by String.unique */
	var a = 'a'.charCodeAt(0), z = 'z'.charCodeAt(0);
	yut.String.unique = function(prefix){
		return (prefix || '') + String.fromCharCode(a + (++counter % (z-a)) ) +''+counter;
	};
})(0);

(function() {
	/* yut.Dom.getId returns element ID, if element does not have an ID
		 it generatse an unique ID for that element, assigns it to the
		 element and returs that new ID.  */
	var unique = yut.String.unique;
	yut.Dom.getId = function(el){
		if (el.constructor === String)
			return arguments.callee($(el));
		else if (!el.id) {
			var id = unique();
			if ($(id)) /* There is already an element with such id, so try again. */
				return arguments.callee(el);
			el.id = 'ka-'+id;
		}
		return el.id;
	};
})();


//dimScreen addon by Brandon Goldman (Modified)
(function($j){
	
	var isFF2 = navigator.userAgent.indexOf('Firefox/2.0') !==-1,
		isIE6 = navigator.appVersion.indexOf('MSIE 6.0') != -1,
		// If Firefox 2, use transparent png instead of transparent background to fix flash popup browser bug
		background = isFF2 ? 'transparent url(http://media.kickstatic.com/kickapps/images/lightbox.png) repeat' : '#000';
	
	$j.extend({
		dimScreen:function(speed,opacity,callback){ 
	    	var placeholder;
			
			if($j('#ka-__dimScreen').size()>0){return;}

			document.documentElement.className += ' ka-dimmed';
			if(typeof speed=='function'){
	        	callback=speed;
	            speed=null;
	        }
	
			if(typeof opacity=='function'){
	        	callback=opacity;
	            opacity=null;
	        }
	
			if(speed<1){
	        	placeholder=opacity;
	            opacity=speed;
	            speed=placeholder;
	        }
	
			if(opacity>=1){
				placeholder=speed;
				speed=opacity;
				opacity=placeholder;
			}
	
			speed=(speed>0)?speed:500;
			opacity=(opacity>0)?opacity:0.5;

  			$j('<div></div>')
	            .attr({id:'ka-__dimScreen',fade_opacity:opacity,speed:speed})
	            .css({
	                background: background,
	                height:( ($j(document).height() >= $j(window).height())? $j(document).height():$j(window).height())+'px',
	                left:'0px',
	                opacity:0,
	                position:'absolute',
	                top:'0px',
	                width: '100%',
	                zIndex:999
	            })
	            .click(function(e){e.stopPropagation()})
	            .appendTo(document.body)
	            .fadeTo(speed,opacity,callback);

	
	           $j(window).bind("resize",function(){
				$j('#ka-__dimScreen').css('height',( ($j(document).height() >= $j(window).height())? $j(document).height():$j(window).height())+'px');
			});
			
			return $j('#ka-__dimScreen');
	    },
	        
	    dimScreenStop:function(callback){
	            var x=$j('#ka-__dimScreen');
	            var opacity=x.attr('fade_opacity');
	            var speed=x.attr('speed');
	            
	            if(navigator.userAgent.indexOf('Firefox/2.0') !==-1){
	            	x.remove();
	
	        		$j(window).unbind("resize",function(){
						$j('#ka-__dimScreen').css('height',( ($j(document).height() >= $j(window).height())? $j(document).height():$j(window).height())+'px');
					});
					                
		            if(typeof callback=='function'){
		            	callback();
		            }
	            }else{
		            x.fadeOut(speed,function(){
		                x.remove();
		                
		                if (isIE6){
							$j('select').each(function(){$j(this).css('visibility','visible');}); 
						}	
		        		
		        		$j(window).unbind("resize",function(){
							$j('#ka-__dimScreen').css('height',( ($j(document).height() >= $j(window).height())? $j(document).height():$j(window).height())+'px');
						});
				
		                if(typeof callback=='function'){
		                	callback();
		                }
		            });
	            }
							$j(document.documentElement).removeClass('ka-dimmed');
	    }
	});
	
})(jQuery);


(function(){
	var $modal = $j(['<div class="ka-modal">',
										'<button type="button" class="ka-main-close ka-close">close</button>',
										'<div class="ka-modal-content"></div>',
									'</div>'].join(''));
	var $modalContent = $j($modal[0].lastChild);

	function event_handlers(e){
		e.stopPropagation();
		var $t = $j(e.target);
		if (!$t.hasClass('ka-close')
				&& $t.parents('.ka-close:first').length == 0)
			return;

		m.close();
		return false;
	}


	var m = yut.Modal = {
		open: function(){
			$j.dimScreen();
			$modal.css({
				'z-index':  1000,
				'top': $j(window).scrollTop() + 100
			});
			$modal.appendTo($j(document.body));
			$modal.click(event_handlers);
			return m;
		},

		setHTMLContent: function(html){
			m.setContent($j(html));
			return m;
		},

		setContent: function(els){
			$modalContent.empty()
				.append(els);
			return m;
		},

		close: function(){
			if (m.onclose){
				m.onclose();
				m.onclose = null;
			}
			$modal.remove();
			$j.dimScreenStop();
			$modal.unbind('click', event_handlers);
		}
	};

	var cache = {};
	m.openWithXhr = function(sUrl, sParams){
		yut.Modal.open();
		var key = sUrl+sParams;
		if (key in cache){
			m.setHTMLContent(cache[key]);
		}	else {
			m.setHTMLContent('<span class="ka-loading">Loading...</span>');
			$j.post(sUrl, sParams,function (response){
				m.setHTMLContent(cache[key] = response);
			});
		}
	};
})();


(function() {
	var m = yut.Modal;

	var c = yut.Confirm = function(title, message, onsuccess, oncancel){
		var $content = $j(yut.String.replaceFromDict(yut.String.TPLS.confirm, {title: title, message: message}));
		$content.click(function(e) {
			var $t = $j(e.target);
			if ($t.hasClass('ka-cancel') && oncancel){
				oncancel();
			}else if (($t.hasClass('ka-submit') || $t.parent().hasClass('ka-submit')) && onsuccess) {
			  if (onsuccess()){
			    m.close();
			  }
			}
		});
		m.open();
		m.setContent($content);
	};

	yut.ConfirmDelete = function(message, onsuccess, oncancel){
		return c('Confirm Delete', message, onsuccess, oncancel);
	};

	yut.ConfirmRemove = function(message, onsuccess, oncancel){
		return c('Confirm Remove', message, onsuccess, oncancel);
	};
})();

(function(){
	$holder = $j(['<div id="ka-notice">',
									'<div class="ka-nw"></div><div class="ka-n"></div><div class="ka-ne"></div>',
									'<div class="ka-notice-content"></div>',
									'<div class="ka-sw"></div><div class="ka-s"></div><div class="ka-se"></div>',
								'</div>'].join(''));

	$holder.hide();

	$content = $holder.find('div.ka-notice-content:first');

	$j(function(){
		$holder.appendTo($j(document.body));
	});

	yut.showNotice = function(msg){
		$holder.show();
		$content.html(msg);
		$holder.css({
			top: yut.pageScroll().top + 150 + 'px',
			'margin-left': '-' + $holder[0].offsetWidth/2 + 'px'
		});

		setTimeout(function(){
			$holder.fadeOut();
		}, ypr.Notice.displayDuration * 1000);
	};
})();



function PopBox(options){
	this.hide = this.hide.bind(this);
	this.hideOnEcapeKey = this.hideOnEcapeKey.bind(this);
	this.reposition = this.reposition.bind(this);
};

(function(pro){
  function clickHandler(e){
    e.stopPropagation();
    var $t = $j(e.target);
    if (!$t.hasClass('ka-close') && $t.parents('.ka-close:first').length == 0) {
			this.TID = setTimeout(this.reposition, 1);
      return;
		}
    this.hide();
  }

  pro.$element = function(){
    if (this.$box)
      return this.$box;
    this.$box = $j('<div class="ka-pop-box">\
<button type="button" title="Close" class="ka-close"><span>Close</span></button>\
<div class="ka-pop-box-content"></div>\
</div>');
    this.$box.click(clickHandler.bind(this));
    return this.$box;
  };

	pro.contentElement = function(){
		return this.$element()[0].lastChild;
	};

	function unbind(c){
    $j(document).unbind('click', c.hideOnEcapeKey);
    $j(document).unbind('keypress', c.hide);
		$j(window).unbind('resize', c.reposition);
		$j(window).unbind('scroll', c.reposition);
		c.$rel = null;
	}

	pro.reposition = function(){
		this.positionToOffset(this.$rel.offset());
	}

	pro.addToDoc = function() {
    this.$box.appendTo(document.body);
	}

	pro.positionToOffset = function(offset){
    var height = Math.max(document.documentElement.scrollTop, document.body.scrollTop) + $j(window).height();
    var width = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) + $j(window).width();
    var bheight = this.$box[0].offsetHeight;
    var bwidth = this.$box.width();

    if ((offset.top + bheight) > height)
      offset.top =  height - bheight;

    if ((offset.left + bwidth) > width)
      offset.left =  width - bwidth;

		this.$box.css(offset);
	};

  pro.show = function($relativeTo, e){
		if (e)
			e.stopPropagation();
		unbind(this);
		this.$rel = $relativeTo;
		this.addToDoc();
		var offset = $relativeTo.offset();
		this.positionToOffset(offset);

    this.$box.show();
		setTimeout(function(){
			$j(document).bind('keypress', this.hideOnEcapeKey);
			$j(document).click(this.hide);
			$j(window).bind('resize', this.reposition);
			$j(window).bind('scroll', this.reposition);
			this.positionToOffset(offset);
		}.bind(this), 1);
  };

	pro.hideOnEcapeKey = function(e){
		if (e && e.type == 'keypress' && !e.isKeyPressed('Escape'))
			return;
		this.hide();
	};

	pro.hide = function(){
		unbind(this);
		this.$box.hide();
		if (this.onhide)
			this.onhide();
	};
})(PopBox.prototype);


function Well(relatedObject){
  this.relatedObject = relatedObject;
}

(function(pro){
	var box = null; /* shared accross all; */

	function onshrink(){
		if (this.onshrink)
			this.onshrink();
		box.onhide = null;
	}

  function show(e){
		e.stopPropagation();
		var $re = this.relatedObject.$element();
		var be = box.contentElement();
		if ($re.parent()[0] != be) {
			be.innerHTML = '';
			$re.appendTo(be);
		}
		if (box.onhide)
			box.onhide();
		box.onhide = onshrink.bind(this);
    box.show(this.$well);

		if (this.onexpand)
			this.onexpand();

  };

  pro.$element = function($root){
		if (!$root)
			$root = $j;
    if (this.$well)
      return this.$well;
    this.$well = $root('<div class="ka-well"><div class="ka-well-arrow"></div></div>');
		this.$value = $root('<div class="ka-well-value"></div>').appendTo(this.$well);
		if (!box)
			box = new PopBox;
    this.$well.click(show.bind(this));
    return this.$well;
  };

	pro.setValue = function(v) {
		if (v != undefined) {
			this.value = v;
			this.$value.html(v);
		}
		return this.value;
	}
})(Well.prototype);
Well.withObjectFor$Element = function(obj, $el) {
	var w = new Well(obj);
	$el.addClass('ka-with-well');
	$el.attr('tabIndex', -1);
	w.$element($el.get$J()).insertBefore($el);
	return w;
};


// all functionality that gets called on DOM ready();
$j(function(){
	$j(ypl.globalMethodNames).each(function() {
		ypl[this]();
	});

	if ('init' in y.Page){
		y.Page.init();
	}
	Yuku.page_loaded = true;
	$j(document.documentElement).removeClass('ka-loading-page');
});
