(function ($) {
	/*
	* Sets the element to a relative position (if not done using CSS)
	* Sets the children to absolute positioning
	* Transitions visibility between the children using a animated effect
	* */
	$.fn.hpslideshow = function (params) {
		var defaults = {
			speed: 2000,
			pause: 3000,
			startIndex: 0,
			transitionCallback: function (index, $curr) { }
		};
		var t = $.extend(defaults, params);

		return this.each(function () {

			var $this = $(this);
			var $children = $this.children();
			var length = $children.length;

			if (length !== 1) {

				var slideInterval;
				var index = t.startIndex;

				var transition = function () {
					var $prev = $($children.get((length + index - 1) % length));
					var $curr = $($children.get(index));
					var $next = $($children.get((index + 1) % length));

					$children.fadeOut(t.speed, function () { });
					$curr.fadeIn(t.speed, function () { });
					t.transitionCallback(index, $curr);
					index = (index + 1) % length;
				};

				slideInterval = setInterval(transition, t.speed + t.pause);
				transition();

				$this.bind('next', function () {
					clearInterval(slideInterval);

					index = (index) % length;
					transition();
					slideInterval = setInterval(transition, t.speed + t.pause);

				}).bind('prev', function () {
					clearInterval(slideInterval);

					index = (length + index - 2) % length;
					transition();
					slideInterval = setInterval(transition, t.speed + t.pause);

				}).bind('jump', function (e, position) {
					clearInterval(slideInterval);

					index = position;
					transition();
					slideInterval = setInterval(transition, t.speed + t.pause);
				});
			} else {
				$children.show();
			}

			$this.css({ 'position': 'relative' });
			$children.css({
				'position': 'absolute',
				'overflow': 'hidden'
			});
		});
	};

	$.fn.branchMap = function (params) {
		var defaults = {
			startLatLng: [-40.7140, 173.6719],
			showOverlay: function (obj) { }
		};
		var t = $.extend(defaults, params);
		var markerPos = [];

		return this.each(function () {
			//alert('map');
			var $this = $(this);

			var latlng = new google.maps.LatLng(-40.7140, 173.6719);

			var map = new google.maps.Map(this, {
				mapTypeId: google.maps.MapTypeId.ROADMAP
			});


			var bounds = new google.maps.LatLngBounds();
			var geocoder = new google.maps.Geocoder();

			$this.bind('addMarkers', function (e, obj) {

				$.each(obj, function (i, n) {

					var image = n['divisionShortName'];

					if (image in {Party: 1, Rhodes: 1, Henderson: 1}) {
						image = new google.maps.MarkerImage('/hirepool/images/marker/blue.png',
							new google.maps.Size(32, 40),
							new google.maps.Point(0, 0),
							new google.maps.Point(16, 32)
						);
					} else {
						image = new google.maps.MarkerImage('/hirepool/images/marker/orange.png',
							new google.maps.Size(32, 40),
							new google.maps.Point(0, 0),
							new google.maps.Point(16, 32)
						);
					}

					var newPos = new google.maps.LatLng(n['latitude'], n['longitude']);

					var marker = new google.maps.Marker({
						position: newPos,
						map: map,
						title: n['divisionName'],
						icon: image
					});

					google.maps.event.addListener(marker, 'click', function () {
						t.showOverlay(n);
					});

					markerPos[markerPos.length] = newPos;
				});

			}).bind('search', function (e, searchString) {
				//alert('searchString: ' + searchString);
				geocoder.geocode({ 'address': searchString, 'region': 'nz' }, function (results, status) {
					//alert('results.length: ' + results.length);
					if (status != google.maps.GeocoderStatus.OK) {
						//alert('status not ok');
						if (searchString) {
							$('.map-branch-listing').before('<p class="error">Your search "' + searchString.replace(/\+/g, ' ') + '" did not return any exact matches, see below for suggested locations.</p>');
						}
						map.setZoom(5);
						map.setCenter(latlng);
					} else {
						//alert('status ok');
						var location = results[0].geometry.location
						//alert(location);
						map.setZoom(12);
						map.setCenter(location);

						/**/
						var getDistance = function(a, b) {
							var dLat = (b.lat() - a.lat()) * Math.PI/180;
							var dLng = (b.lng() - a.lng()) * Math.PI/180;
							var distance = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(a.lat() * Math.PI /180) * Math.cos(b.lat() * Math.PI/180) * Math.sin(dLng/2) * Math.sin(dLng/2);
							return 2 * Math.atan2(Math.sqrt(distance), Math.sqrt(1-distance));
						}

						var distance = 0;
						for (var i in markerPos) {
							if (getDistance(markerPos[i], location) < getDistance(markerPos[distance], location))
								distance = i;
						}
						bounds = map.getBounds();
						bounds.extend(markerPos[distance]);
						map.fitBounds(bounds);

						if (map.getZoom() < 5) {
							if (searchString) {
								$('.map-branch-listing').before('<p class="error">Your search "' + searchString.replace(/\+/g, ' ') + '" did not return any exact matches, see below for suggested locations.</p>');
							}
							map.setZoom(5);
							map.setCenter(latlng);
						}
						/**/
					}
				});
			});
		});
	};

	$.fn.selectorator = function (params) {
		var defaults = {
			copyClasses: true
		};
		var t = $.extend(defaults, params);

		return this.each(function () {
			var $this = $(this);

			$this.hide();
			var $options = !$this.find('optgroup').length ? $this.children() : $this.find('optgroup'),
			isOptgroup = $options.first().is('optgroup'),
			$selected = isOptgroup ? $this.find('option[selected]') : $options.filter('[selected]');

			var selectedText = $selected.html() ? $selected.html() : '';
			var classes = t.copyClasses ? ' ' + $this.attr('class') : '';

			var $fake = $('<div class="fake-select' + classes + '"></div>').insertAfter($this);
			var $curr = $('<span>' + selectedText + '</span>').appendTo($fake);
			var $list = $('<ul />').appendTo($fake);

			$fake.click(function (e) {
				e.stopPropagation();
				if ($fake.hasClass('open'))
					$fake.removeClass('open');
				else if (!$this.attr('disabled'))
					$fake.addClass('open');
			});

			$(document).click(function () {
				$fake.removeClass('open');
			});

			var $fakeOptsStr = "";
			if(isOptgroup){
			    $options.each(function (e, q) {
				    $fakeOptsStr += '<li data-label="' + $(q).attr('label') + '">' + $(q).attr('label') + '<ul>';
				    $(q).children().each(function (i, n) {
				        $fakeOptsStr = $fakeOptsStr + '<li data-val="' + $(n).attr('value') + '">' + $(n).html() + '</li>';
			        });
			        $fakeOptsStr += "</ul></li>";
			    });
			} else {
			    $options.each(function (i, n) {
				    $fakeOptsStr = $fakeOptsStr + '<li data-val="' + $(n).attr('value') + '">' + $(n).html() + '</li>';
			    });
			}
			var $fakeOpts = isOptgroup ? $($fakeOptsStr).appendTo($list).find('li[data-val]') : $($fakeOptsStr).appendTo($list);
            
			$fakeOpts.click(function () {
				$curr.html($(this).html());
				$this.val($(this).attr('data-val'));
				$fake.removeClass('open');
				$this.trigger('change');
				return false;
			});
		});
	};

    $.fn.showIfChecked = function (params) {
		var defaults = {
            $elementToToggle: $("#delivery-input-fields")
	    };
	    var args = $.extend(defaults, params);
        var $collection = this;
        args.$elementToToggle.toggle($collection.is(":checked"));
	    return this.each(function () {
            var $this = $(this);
            $this.change( function() {
                args.$elementToToggle.toggle($collection.is(":checked"))
            });
        });
	};




	$.fn.somePlugin = function (params) {
		var defaults = {
	};
	var t = $.extend(defaults, params);

	return this.each(function () {
	});
};

})(jQuery);
