/* 
 * jQuery.compro
 */

(function($){
	$.fn.pluck = function(key) {
		var plucked = [];
		this.each(function() {
			plucked.push($(this).attr(key))
		});
		return plucked;
	};
	
	$.fn.setNext = function() {
		var _id, m, l, reid = /(.*)_(\d+)([^\d-]*)$/, renm = /(.*?)(?:_(\d+))?(_?[^\[\]_]+)?(\])?$/;
		this.each(function() {
			var $t = $(this);
			
			if (_id = $t.attr('id')) {
				var n = 0, p = '', t = _id;
				if (m = _id.match(reid)) {
					n = parseInt(m[2]);
					p = m[3];
					t = m[1];
				}
				while($('#' + (l = t + '_' + ++n + p)).length);
				$t.attr('id', l);
				$('[for="' + _id + '"]').attr('for', l);
			}
			if (_id = $t.attr('name')) {
				var n = 0, p = '', t = _id, e = '';
				if (m = _id.match(renm)) {
					if (m[3] && !m[1] && !m[2]) {
						t = m[3];
					} else if (!m[2] && m[1] && m[3]) {
						t = m[1] + m[3];
						e = m[4] || '';
					} else {
						n = parseInt(m[1] ? m[2] || 0 : 0);
						t = !m[1] ? m[3] : m[1];
						p = m[3] || '';
						e = m[4] || '';
					}
				}
				while($('[name="' + (l = t + '_' + ++n + p + e) + '"]').length);
				$t.attr('name', l);
			}
		});
		return this;
	}
	
	$.fn.valHook = function(hook, fnMatch, fnGet, fnSet) {
		if (!$.valHooks) $.valHooks = {};
		$.valHooks[hook] = $.valHooks[hook] || {};
		if (fnGet) {
			$.valHooks[hook].getHooks = $.valHooks[hook].getHooks || [];
			if ($.valHooks[hook].get && $.valHooks[hook].get != $.fn.valHook.get) {
				$.valHooks[hook].getHooks.push([undefined, $.valHooks[hook].get, 0]);
			}
			$.valHooks[hook].get = $.fn.valHook.get;
			$.valHooks[hook].getHooks.push([fnMatch, fnGet, {}, hook]);
		}
		if (fnSet) {
			$.valHooks[hook].setHooks = $.valHooks[hook].setHooks || [];
			if ($.valHooks[hook].set && $.valHooks[hook].set != $.fn.valHook.set) {
				$.valHooks[hook].setHooks.push([undefined, $.valHooks[hook].set, 0]);
			}
			$.valHooks[hook].set = $.fn.valHook.set;
			$.valHooks[hook].setHooks.push([fnMatch, fnSet, {}, hook]);
		}
	}
	
	$.fn.valHook.get = function(elem) {
		var hooks = this.getHooks || [];
		var ret = undefined;
		$.each(hooks, function() {
			if (!this[2][elem.id]) {
				this[2][elem.id] = 1;
				if (!this[0] || this[0](elem)) {
					ret = this[1](elem);
					delete this[2][elem.id];
					return false;
				}
				delete this[2][elem.id];
			}
		});
		return ret;
	}
	
	$.fn.valHook.set = function(elem, value) {
		var hooks = this.setHooks || [];
		var ret = undefined;
		$.each(hooks, function() {
			if (!this[2][elem.id]) {
				this[2][elem.id] = 1;
				if (!this[0] || this[0](elem)) {
					this[1](elem, value);
					delete this[2][elem.id];
					ret = true;
					return false;
				}
				delete this[2][elem.id];
			}
		});
		return ret;
	}

	/*
	$('form').live('submit', function() {
		alert('asd');
		return false;
	});
	*/
	$.fn.autocomplete = function(url, fnToString) {
		this.ajaxlookup(function(data) {
			var $this = $(this);
			var $ac = $('#autocomplete');
			if (!$ac.length) {
				$ac = $('<ul>').attr({id:'autocomplete'});
			} else {
				$ac.empty().detach();
			}
			var height = parseInt($this.css('height') || 0)
				+ parseInt($this.css('paddingTop') || 0)
				+ parseInt($this.css('paddingBottom') || 0)
				+ parseInt($this.css('borderBottomWidth') || 0)
				+ parseInt($this.css('borderTopWidth') || 0);
			$ac.insertAfter(this).clonePosition(this, {setWidth:false, setHeight:false, offsetTop:height});
			$.each(data, function() {
				$ac.append($('<li>').append(fnToString && fnToString.call(this) || this.toString()));
			});
		}, url);
	}
	
	$.fn.ajaxlookup = function(fn, url) {
		function ac() {
			var t = this;
			if (typeof t.ac_c == 'undefined') {
				t.ac_c = {};
			}
			var val = $(t).val();
			clearTimeout(t.ac_t);
			if (t.ac_c[val]) {
				fn.call(t, t.ac_c[val]);
			} else {
				t.ac_t = setTimeout(function() {
					if (t.ac_rv != val) {
						if (t.ac_r) {
							t.ac_r.abort();
						}
						t.ac_r = $.ajax({
							url:(typeof url == 'function' ? url.apply(t) : url || document.location),
							data:$(t),
							success:function(data) {
								t.ac_r = null;
								fn.call(t, t.ac_c[val] = data);
							}
						});
					}
				}, 220);
			}
		}
		return arguments.length > 0 ?
			this.bind('keyup click change', ac) :
			this.each(ac);
	}
	
	Function.prototype.curry = function() {
		if (!arguments.length) return this;
		var __method = this, args = arguments;
		return function() {
		  return __method.apply(this, [].concat(args, arguments));
		}
	};
	
	Function.prototype.bind = function (context) {
		if (arguments.length < 2 && typeof arguments[0] === "undefined") return this;
		var __method = this, args = Array.prototype.slice(arguments, 1);
		return function() {
			return __method.apply(context, [].concat(args, arguments));
		}
	}
	
	$.fn.identify = function(prefix) {
		prefix = prefix || 'anonymous_element';
		if (!$.fn.identify.i) {
			$.fn.identify.i = 0;
		}
		return this.each(function() {
			if($(this).attr('id')) return;
			do { 
				var id = prefix + '_' + ++$.fn.identify.i;
			} while($('#' + id).length > 0);            
			$(this).attr('id', id);
		}).first().attr('id');
	};
	
	$.fn.playMe = function() {
		this.click(function() {
			var $this = $(this);
			var flashVars = $this.attr('flashvars');
			flashVars = (flashVars?$.parseJSON(flashVars):{});
			var params = $this.attr('flashparams');
			params = (params?$.parseJSON(params):{});
			var height = $this.height();
			var width = $this.width();
			if (flashVars['flv']) {
				swfobject.embedSWF("http://media.compro.se/swf/player_flv_maxi.swf", $this.identify(), width, height, "9.0.115", "http://media.compro.se/common/swfobject/expressInstall.swf", flashVars, params);
			} else if (flashVars['youtube']) {
				$this.html("<object width='" + flashVars['width'] + "px' height='" + flashVars['height'] + "px'><param name='movie' value='http://www.youtube-nocookie.com/v/" + flashVars['youtube'] + "?rel=0" + (flashVars['autoplay']?'&autoplay=1':'') + "'></param><param name='allowFullScreen' value='true'></param><param name='allowscriptaccess' value='always'></param><embed src='http://www.youtube-nocookie.com/v/" + flashVars['youtube'] + "?rel=0" + (flashVars['autoplay']?'&autoplay=1':'') + "' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='" + flashVars['width'] + "px' height='" + flashVars['height'] + "px'></embed></object>");
			} else if (flashVars['html']) {
				$this.html(flashVars['html']);
			}
		});		
	};
	
	$.fn.clonePosition = function(source, options) {
		var options = $.extend({
			setLeft: true,
			setTop: true,
			setWidth: true,
			setHeight: true,
			offsetTop: 0,
			offsetLeft: 0
		}, options || {});

		var p = $(source).offset();

		this.each(function(index, element) {
			var delta = {top:0, left:0};
			var parent = null;
			var $element = $(element);
			if ($element.css('position') == 'absolute') {
				parent = $element.offsetParent();
				delta = parent.offset();
				parent = parent.get(0);
			}
			
			if (parent == document.body) {
				delta['left'] -= document.body.offsetLeft;
				delta['top'] -= document.body.offsetTop;
			}

			if (options.setLeft) {
				element.style.left = (p['left'] - delta['left'] + options.offsetLeft) + 'px';
			}
			if (options.setTop) {
				element.style.top = (p['top'] - delta['top'] + options.offsetTop) + 'px';
			}
			if (options.setWidth) {
				element.style.width = source.offsetWidth + 'px';
			}
			if (options.setHeight) {
				element.style.height = source.offsetHeight + 'px';
			}
		});
		return this;
	};
	
	$.fn.periodicalExecuter = function (callback, frequency) {
		$.extend(pe = {}, {
			initialize: function(callback, frequency) {
				this.callback = callback;
				this.frequency = frequency;
				this.currentlyExecuting = false;
				this.registerCallback();
			},
			registerCallback: function() {
				this.timer = setInterval(jQuery.proxy(this.onTimerEvent, this), this.frequency);
			},
			execute: function() {
				this.callback(this);
			},
			stop: function() {
				if (!this.timer) {
					return;
				}
				clearInterval(this.timer);
				this.timer = null;
			},
			onTimerEvent: function() {
				if (!this.currentlyExecuting) {
					try {
						this.currentlyExecuting = true;
						this.execute();
					} catch(e) {
						/* empty catch for clients that don't support try/finally */
					}
					finally {
						this.currentlyExecuting = false;
					}
				}
			}
		});
		pe.initialize(callback, frequency);
		return pe;
	};
	
	$.fn.clearForm = function() {
		// iterate each matching form
		return this.each(function() {
			// iterate the elements within the form
			$(':input', this).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 = -1;
				}
			});
		});
	};
	
	$('select[href]').live('change', function() {
		document.location = ($t = $(this)).attr('href').replace(/(%\w+)\b/g, function(m, key, value) {
			var t = $t.get(0);
			return $(t.options[t.selectedIndex]).attr(key.substr(1));
		});
	});
	
	$(function() {
		$('a.email[name]').each( function( index, value ) {
			$(this).attr('href', 'mailto:' + $(this).attr('name').replace('//','@').replace(/\//g,'.'));
			$(this).html( $(this).html().replace(' [at] ', '@').replace(' DOT ', '.') );
		});
		
		$('input[defValue]').each(function() {
			element = $(this);
			!element.val() ? element.val(element.attr('defValue')) : '';
			element.focus(function() {$(this).val() == $(this).attr('defValue') ? $(this).val('') : ''});
			element.blur(function() {!$(this).val() ? $(this).val($(this).attr('defValue')) : ''});
			if (_form = element.closest('form')) {
				element.closest('form').submit(function() {
					if (this.val() == this.attr('defValue')) {
						this.val('');
					}
				}.bind(element));
			}
		});
			
	});
	
	$('img[copyright]').live('mouseover mouseout', function(event) {
		var $t = $(this);
		var $p = $t.offsetParent();
		var $e = $('#__imageCaption');
		if (event.type == 'mouseover') {
			var pos = $t.position();
			if (!$e.size()) {
				$e = $('<div>', {id:'__imageCaption', class:'image-caption'}).css({
					fontSize:'80%',
					position:'absolute',
					color:'white',
					padding:'5px',
					'-moz-box-sizing':'border-box',
					'-webkit-box-sizing':'border-box',
					boxSizing:'border-box',
					background:'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAE0lEQVQY02NgYGA4QyQeVUhPhQBds0+xiYR8pwAAAABJRU5ErkJggg==)'
				}).bind('mouseout', function() {
					$t.trigger('mouseout');
				});
				$(document.body).append($e);
			}
			$e.css({width:$t.width(), left:pos.left + parseInt($t.css('marginLeft') || 0) + parseInt($t.css('borderLeftWidth') || 0) + parseInt($t.css('paddingLeft') || 0)}).text($t.attr('copyright'));
			$e.css({top:$t.outerHeight() - $e.outerHeight() - parseInt($t.css('borderBottomWidth') || 0)});
			$e.show();
		} else {
			$('#__imageCaption').not(event.relatedTarget).hide();
		}
	});

})(jQuery);
