$.flashVersion = function() {
	var version = [0, 0, 0];

   if (navigator.plugins && navigator.mimeTypes.length) {
		var plugin = navigator.plugins["Shockwave Flash"];

		if (plugin && plugin.description) {
			version = plugin.description.split(" ");
			version = version[2] + '.' + String(version[4]).slice(1);
			version = version.split(".");
		}
	}
	else {
		try {
			var plugin = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			for (var i = 3; plugin != null; i++) { plugin = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i); }
			i--;
		}
		catch(error) { }

		if (i == 6) {
      	version = new Array(6, 0, 0);
		}
      else if (i > 2) {
			try { var version = plugin.GetVariable("$version").split(" ")[1].split(","); }
			catch(error) { }
		}
	}

	return new Array(parseInt(version[0]), parseInt(version[1]), parseInt(version[2]));
}


$.userAgent = String(navigator.userAgent).toLowerCase();
$.browser.iphone = ($.userAgent.indexOf('iphone') !== -1);
$.browser.ipad = ($.userAgent.indexOf('ipad') !== -1);


$.extend({
	delegate: function(fn, thisObject) {
      var parameters = Array.prototype.slice.call(arguments).slice(2);
 
      return function() {
         return fn.apply(thisObject || this, parameters.concat(Array.prototype.slice.call(arguments)));
      };
	}
});


$.email = function($value) {
	return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test($value);						
}


$.popup = function(url, width, height, scrolling)
{
	if (scrolling == undefined) scrolling = 0;

	var x = (screen.width / 2) - (width / 2);
	var y = (screen.height / 2) - (height / 2);
	var properties = "toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=" + scrolling + ",resizable=0,width=" + width + ",height=" + height + ",top=" + y + ",left=" + x;
	var popup;

	popup = window.open(url, 'default', properties);
	popup.focus();
}


$.widget('ui.validate', {

	_create: function() {
   	var $fields = this.fields();

      this.form = this.element.filter('form');

		if (this.form.length > 0) {
      	this.form.unbind('submit').submit($.delegate(this.submitCallback, this));
      }
      else {
      	this.element.find('button[type=submit]').unbind().click($.delegate(this.submitCallback, this));
      }
		
		this.element.find('button[type=reset]').click($.delegate(this.reset, this));

      this.update();

      for (var $i = 0; $i < $fields.length; $i++) {
      	$fields.eq($i).trigger('blur');
      }
	},
	
	
	reset: function(event) {
		if (event) event.preventDefault();
		
		this.fields().each(function() {
			$(this).val($(this).attr('title'));							 
		});
	},


   submitCallback: function(event) {
      if ($(event.target).filter('form').length == 0) event.preventDefault();
      return this.validate();
   },


   update: function() {
   	var $fields = this.fields();
      var $field;
  
		for (var $i = 0; $i < $fields.length; $i++) {
			$field = $fields.eq($i);
         $field.data('validator', this);
			if ($field.data('type') == null) {
         	$field.data('type', $field.attr('type'));
 				$field.unbind();
            $field.focus($.delegate(this.focus, this));
            $field.blur($.delegate(this.blur, this));
         }
		}
   },
   
   
	focus: function(event) {
      var $field = $(event.target);
      
      if ($field.val() == $field.attr('title')) {
         $field.val('');
         this.clone($field, true);
      }
   },
   
   
   blur: function(event) {
      var $field = $(event.target);

      if ($field.val().length == 0) {
         $field.val($field.attr('title'));
         this.clone($field, false);
      }
   },


	fields: function() {
		return this.element.find('input, textarea, select').filter(':visible');
	},


	clone: function($field, password) {
		var type = $field.data('type');
      var attributes = ['id', 'class', 'style', 'type', 'title', 'name', 'value'];
      var attribute;
      var html;
      var $clone;
      
      if ($field.attr('type') == (password ? 'password' : 'text')) return;

		if (type == 'password') {
         html = "<input type=\"" + (password ? 'password' : 'text') + "\"";
 
         for (var i = 0; i < attributes.length; i++)
         {
         	attribute = $field.attr(attributes[i]);

            if (attribute != null) {
            	html += attributes[i] + "=\"" + attribute + "\"";
            }
         }

         html += "></input>";
 
         $field.after(html);
         $clone = $field.next();
         $field.remove();
         this.update();
         $clone.data('type', type);
         if (password) $clone.focus();
		}
	},


	validate: function() {
		var $fields = this.fields();
      var $field;
      var values = {};
      var value;
      var parts, part;
      var valid;
		var result = true;
      var errors = {};
      var error;

		for ($i = 0; $i < $fields.length; $i++) {
			$field = $fields.eq($i);
 
         if ($field.data('validator') == this) {
            value = ($field.val() == $field.attr('title') ? '' : $field.val());
            parts = $field.attr('class').split(" ");
            part = null;
   
            for ($j = 0; $j < parts.length; $j++) {
               if (parts[$j].slice(0, 8) == 'validate') {
                  part = parts[$j].slice(9, -1).split(',');
                  break;	
               }
            }
 
            if (part != null) {
               switch (part[0]) {
                  case 'email': valid = $.email(value); break;
						case 'number': valid = (Number(value) > 0); break;
                  default: valid = (value.length >= 2);
               }

               $field.toggleClass('error', !valid);
               errors[$field.attr('name')] = !valid;
               values[$field.attr('name')] = value;
   
               if (!valid) result = false;
            }
         }
		}
 
		if (this.options.submit != null)
      {
      	this.options.submit.apply(this.element[0], [result, errors, values]);
      	return false;
      }

		if (result) this.cleanup();
		return result;
	},
 
 
   cleanup: function() {
   	var $fields = this.fields();
      var $field;

      for (var i = 0; i < $fields.length; i++) {
         $field = $fields.eq(i);
         if ($field.val() == $field.attr('title')) $field.val('');
      }
   },


   submit: function() {
   	this.cleanup();
      this.element[0].submit();
   },
   
   
   serialize: function(object) {
   	var $fields = this.element.find('input, textarea, select');
      var $field;
      var data = {};
      var value;
      var name;
      var parts;

      for (var i = 0; i < $fields.length; i++) {
      	$field = $fields.eq(i);
         name = $field.attr('name');
         value = $field.val();
         parts = name.split(']').join('').split('[');
 
         if (object && parts.length > 1) {
         	if (!data[parts[0]]) data[parts[0]] = {};
            data[parts[0]][parts[1]] = value;
         }
         else {
         	data[name] = value;
         }
      }

		if (object) return data;
      return $.param(data);
   },
   
   
   clear: function() {
   	this.fields().val('');
   }

});


$.widget('ui.scrollable', {

	_create: function() {
		this.buttons = this.element.find('.button1:first, .button2:first');
   	this.buttons.unbind().bind('click', this, function(event) {
         event.preventDefault();
			if ($(this).hasClass('disabled')) return;
			event.data.change(($(this).hasClass('button1') ? '-1' : '1'));
      });

      this.change(1);
   },
	
	
	update: function() {
		this.change(this.index);
	},


   change: function(offset)
   {
   	var vertical = (this.options.type == 'vertical');
   	var index = this.index;
		var $parent = this.element.find('.items:first');
		var $container = $parent.find('> *:first');
      var $items = $container.find('> *:visible');
      var $item = $items.eq(0);
      var length = (vertical ? $item.outerHeight() : $item.outerWidth());
      var spacing = parseInt($item.css((vertical ? 'marginBottom' : 'marginRight')), 10);
		var count = Math.floor(((vertical ? $parent.height() : $parent.width()) + spacing) / (length + spacing));
      var total = Math.ceil($items.length / count);
      var data = {};
		var offset;

      switch (offset) {
      	case '-1': index = (index == 1 ? total : index - 1); break;
         case '1': index = (index == total ? 1 : index + 1); break;
			default: index = offset;
      }

		index = Math.max(1, Math.min(index, total));
		offset = -(length + spacing) * Math.min($items.length - count, (count * (index - 1)));
		offset = Math.min(0, offset);

      if (vertical) {
         data.marginTop = offset;
      }
      else {
         data.marginLeft = offset;
      }

      this.index = index;
		
      $container.stop(true).animate(data, 1000);
		this.buttons.eq(0).toggleClass('disabled', (this.index == 1));
		this.buttons.eq(1).toggleClass('disabled', (this.index == total));
   }

});


/*
$.widget('ui.popup', {

	_create: function() {
		if ($.browser.msie) {
			$(window).scroll($.prefix(this.scroll, this));
         this.scroll();
		}

      $(window).resize($.delegate(this.resize, this));
	},


	show: function(snippet, data, callback) {
      var $element;      
		var data = (data == null ? snippet : $.snippet($.snippets['frame/popup/' + snippet], data));

		if (callback == null) callback = function() { };

		this.element.html(data);
		this.element.show();

		$element = this.element.find('.close, .cancel');
		$element.unbind();
		$element.bind('click', this, function(event) {
			event.data.hide();
		});

      this.resize();

      if (!$.browser.msie) {
         this.element.fadeTo(0, 0);
      	this.element.fadeTo(500, 1, function() {
            callback();
         });
      }
      else {
      	this.callback();
      }
	},
   
   
   resize: function() {
   	$element = this.element.find('.popup-content > *:first');

      if (parseInt($element.css('top'), 10) > 0) $element.css('margin-top', -Math.round($element.outerHeight() / 2) + 'px');
   },
	
	
	scroll: function() {
		this.element.css('top', $(window).scrollTop() + 'px');
	},


	hide: function() {
   	if (!this.element.is(':visible')) return;
      
      this.element.find('embed, object').hide();
   
   	if ($.browser.msie) {
      	this.element.hide(); 
      }
      else {
      	this.element.fadeTo(500, 0, $.delegate(this.hideComplete, this));
      }
	},
   
   
   hideComplete: function() {
   	this.element.html('');
   	this.element.hide();
  	}

});
*/


$.widget('ui.popup', {

	_create: function() {	
		$('a').click($.delegate(this.click, this));
		this.animate = !($.browser.msie);
		this.items = this.element.find('.popup-container > *');
		this.items.find('.close, .cancel').click($.delegate(this.hide, this));
	},

	
	click: function(event) {
		var styles = $(event.currentTarget).attr('class').split(' ');
		var style;
		var title;
		
		for (var i = 0; i < styles.length; i++) {
			style = styles[i];
			
			if (style.slice(0, 6) == 'popup-') {
				title = style.slice(6);
				break;	
			}
		}
		
		if (!title) return;

		event.preventDefault();
		this.show(title);
	},
	
	
	show: function(title) {
		var $items;

		this.items.hide();
		this.container = this.items.filter('.' + title);
		this.container.show();
		
		if (this.animate) {
			this.element.fadeTo(500, 1);	
		}
		else {
			this.element.show();
		}
	},
	
	
	hide: function() {
		if (this.animate) {
			this.element.fadeTo(500, 0, $.delegate(this.hideComplete, this));	
		}
		else {
			this.element.hide();
		}
	},
	
	
	hideComplete: function() {
		this.element.hide();	
	}
	
});


$.widget('ui.gallery', {

	_create: function() {
   	var data = this.options.data;
      var value;
      var extension;
		var index;
		var $button;
      
		this.flash = ($.flashVersion()[0] >= 7);
      this.viewer = this.element.find('.viewer ul');
      if (this.viewer.length == 0) this.viewer = this.element.find('.viewer');
		if (this.viewer.length == 0) this.viewer = this.element;

		this.element.find('.button1, .button2').unbind().bind('click', this, function(event) {
			event.data.change(($(this).hasClass('.button1') ? '-1' : '1'));
		});
		this.buttons = this.element.find('ul li a[class=]');

		for (var i = 0; i < this.buttons.length; i++) {
			$button = this.buttons.eq(i);
			index = parseInt($button.attr('rel'), 10);
			if (isNaN(index) || index == 0) index = this.buttons.index($button) + 1;
			$button.attr('rel', index);
		}

		this.buttons.unbind().bind('click', this, function(event) {
      	event.data.change(parseInt($(this).attr('rel'), 10));
      });
		
		i = 0;

      if (data == null) {
      	data = [];

         if (this.viewer.filter('ul').length > 0) {
				this.viewer.find('> li').each(function() {
            	data.push($('<div />').append(this).html());
            });
         }
         else {
            this.viewer.find('img').each(function() {
               data.push($(this).attr('rel'));
            });

            while (i < data.length) {
					extension = String(data[i]).split('.').pop().toLowerCase();
               
               if (!this.flash && $.inArray(extension, ['flv', 'f4v']) != -1) {
                  data.splice(i, 1);
               } 
               else {
                  i++;
               }
            }
         }
         
         this.data = data;
      }

		this.viewer.html('');
      this.enabled = true;
      
		if (this.data.length > 0) this.change(1);
	},
   
   
   play: function() {
   	this.pause();
   	this.interval = setInterval($.delegate(this.change, this, '1'), 5000);
   },


   pause: function() {
   	if (this.interval == null) return;
   	clearInterval(this.interval);
      this.interval = null;
   },


	change: function(offset) {
		if (!this.enabled) return;

		var data = this.data;
		var index = Number(this.index);
		
		switch (offset) {
			case '-1': index = (index == 1 ? data.length : index - 1); break;
			case '1': index = (index == data.length ? 1 : index + 1); break;
			default: index = offset;	
		}

		if (isNaN(index) || index == this.index) return;
		if (this.container) {
			this.container.find('img').stop(true);
			this.container = null;	
		}

		this.index = index;
		this.buttons.removeClass('active').filter('[rel=' + index + ']').addClass('active');
		this.enabled = false;
      this.pause();
		this.fade();

		if (this.options.change) this.options.change(index);
	},


	fade: function() {
     	var value = this.data[this.index - 1];
      var $items;
      var $item;
      var $image;
      var extension = String(value).split('.').pop().toLowerCase();
      var html;
		var type;
		var url;
		var info;
		var flash;

		if (value.indexOf('youtube.com') !== -1) type = 'youtube';
		else if (value.indexOf('vimeo.com') !== -1) type = 'vimeo';
		
		info = $.url.parse(value);

      if (type || $.inArray(extension, ['flv', 'f4v']) != -1) {
			this.viewer.html("<div class=\"video\" style=\"position: absolute; z-index: 1;\"></div>");
      	
			if (this.flash) {
				switch (type) {
					case 'youtube': url = 'http://www.youtube.com/v/' + info.params.v + '&hl=en_US&fs=1&'; break;
					case 'vimeo': url = "http://vimeo.com/moogaloop.swf?clip_id=" + info.directory.slice(1) +"&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ec008c&amp;fullscreen=1"; break;
					default: url = this.options.player;
				}
	
				flash = new SWFObject(url, null, '100%', '100%', '8', '#d4d4d4');
				flash.addParam('allowScriptAccess', 'always');
				flash.addParam('allowFullScreen', 'true');
				flash.addVariable('url', value);
				flash.write(this.viewer.find('> *:last')[0]);
			}
			else {
				switch (type) {
					case 'youtube': html = "<object width=\"100%\" height=\"100%\"><param name=\"movie\" value=\"" + value + "\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"" + value + "\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"100%\" height=\"100%\"></embed></object>"; break;
					case 'vimeo': html = "<video src=\"http://www.vimeo.com/play_redirect?clip_id=" + info.directory.slice(1) + ($.browser.iphone ? "&quality=" : "") + "\" controls=\"controls\" preload=\"preload\" width=\"000\" height=\"000\"></video>"; break;
				}

				this.viewer.find('> *:last').html(html);
			}

         this.enabled = true;
      }
      else {
         if ($.inArray(extension, ['png', 'gif', 'jpg', 'jpeg']) != -1) {
         	html = "<img src=\"" + value + "\" style=\"position: absolute; z-index: 1;\" />";
         }
         else {
         	html = value;
         }

         this.viewer.append(html);
         $items = this.viewer.find('> *');
         $item = $items.filter(':last');
         $item.fadeTo(0, 0);

         if (String($item[0].nodeName).toLowerCase() == 'img') $image = $item;
         else $image = $item.find('img');

         $image.load($.delegate(this.imageLoad, this, $items, $item));
		}
	},

   
   imageLoad: function($items, $item) {
   	$item.fadeTo(1000, 1, $.delegate(this.fadeComplete, this, $items, $item));
		
		this.container = $item;
		this.animate(false);
   },

   
   fadeComplete: function($items, $item) {
      if ($items.length > 1) $items.eq(0).remove();

		this.animate(true);
		if (this.options.delay !== 0) this.play();
      this.enabled = true;
   },


	animate: function(animate) {
		var $image = this.container.find('img');

		if ($image.length == 0 || $image.width() <= this.container.width()) return;

		$image.css('margin-left', -Math.round(($image.width() - this.container.width()) / 2) + 'px');

		if (!animate) return;

		$image.animate({ 'margin-left': 0 }, { duration: 2000, easing: 'easeInOutSine' });
	}

});
