var Expo = function() {

	return {	
		init: function() {
			Expo.addAnchors.init([
				{ element: ".teaser-type-1", include: ["P", "IMG"] },
				{ element: ".teaser-type-2", include: ["P", "IMG"] },
				{ element: ".news-teaser", include: ["P", ".image IMG"] },
				{ element: ".teaser-list .teaser", include: ["P", "IMG"] },
				{ element: ".search-result", include: [".search-result-content"] },
				{ element: ".calendar-teaser", include: [".dtstart"] }
			]);
			Expo.form.init();
			Expo.slideshow.init();
			Expo.calendar.init();
		},

		scrollTo: function(el) {
			window.scrollTo(0, Math.max($(el).offset().top, 0));
		}
	};
}();


Expo.StringBuffer = function() {
	this.buffer = [];
}
Expo.StringBuffer.prototype.append = function append(str) {
	this.buffer.push(str);
	return this;
};
Expo.StringBuffer.prototype.toString = function toString() {
	return this.buffer.join("");
};


/**
 * Adds anchors around an elements inner elements when hovered.
 * Sets a class of "hover" on the parent element when its
 * children are being hovered.
 */
Expo.addAnchors = function(){	
	var selectors = "";
	return {
		init: function(settings) {
			if (settings) {
				for (var i = 0, ln = settings.length; i < ln; i++) {
					var noOfParams = settings[i].length;
					if (settings[i].element) {
						if (settings[i].include) {
							var selector = settings[i].element;
							selectors += (selectors.length > 0 ? "," : "") + selector;
							for (var j = 0, ln2 = settings[i].include.length; j < ln2; j++) {
								$(selector + " " + settings[i].include[j]).live("mouseover", function() {
									var $self = $(this);
									var $linkParent = $self.data("linkParent");
									if (!$linkParent || typeof($linkParent) == "undefined") {
										$linkParent = $self.closest(selectors);
										if ($linkParent.length > 0) {
											$self.data("linkParent", $linkParent);
											var href = $linkParent.find("a").attr("href");
											if (href != null) {
												$a = $("<a href=\"" + href + "\" class=\"added-anchor\"></a>");
												if ($self.html() == 0) {
													$self.before($a);
													$a.wrapInner($self);
												} else if ($self.find("a").length == 0) {
													$self.wrapInner($a);
												}
											}										
										}
									}
									if ($linkParent) {
										$linkParent.addClass("hover");
									}
								});
								$(selector + " " + settings[i].include[j]).live("mouseout", function() {
									var $linkParent = $(this).data("linkParent");
									if ($linkParent != null) {
										$linkParent.removeClass("hover");
									}
								});
							}
						}
					}
				}
			}
		}
	};
}();


/**
 * Form
 * Validates a form
 */
Expo.form = function() {
	var validateField = function(field) {
		var form = field.form;
		var $el = $(field);
		if (($el.hasClass("required") && (jQuery.trim(field.value) == "")) ||
			($el.hasClass("accept-conditions") && !field.checked) ||
			($el.hasClass("email") && jQuery.trim(field.value) != "" && field.value.search(/(\w|\.|\-)+\@(\w|\.|\-)+\.[a-z]{2,6}$/))) {
			form.erronous.push($el);
			form.hasErrors = true;
		} else {
			$el.removeClass("has-error");
		}
	};
	
	var alertUser = function(form) {
		for (var i = 0, ln = form.erronous.length; i < ln; i++) {
			form.erronous[i].addClass("has-error");
			form.erronous[i].effect("shake", {distance: 2}, 40);
		}
	};
	
	var DOMReady = function() {
		$("form.validate").submit(function() {
			return Expo.form.validate(this);
		});
	};

	return {
		init: function() {
			$("form .has-error").live("keyup", function() {
				validateField(this);
				return false;
			});
            $(document).ready(DOMReady);
		},
		
		/**
		 * Validates a submitted form (or this if it's run on an element)
		 */
		validate: function(form) {
			form.erronous = [];
			form.hasErrors = false;
			
			$(form).find("input, textarea").each(function() {
				validateField(this);
			});
			if (form.hasErrors) {
				alertUser(form);
				return false;
			} else {
				return true;
			}
		},
		
		reset: function(form) {
			form.reset();
			$(form).find("input, textarea").removeClass("has-error");
		},
		
		submitWithAjax: function(form, callback) {
			var data = $("form").serialize();
			data += "&ajax=true";
			$.post(form.getAttribute("action"), data, callback, "json");
		}
	};
}();


/**
 * AJAX Form Class
 * @param {Object} form
 */
Expo.AJAXForm = function(form) {
	form = $(form);
	form.isAJAXForm = true;
	form.beforeSubmissionHandler = function () { return true; };
	form.addEvent("submit", Expo.AJAXForm.sendForm);
	form.setBeforeSubmissionHandler = function(fn) {
		this.beforeSubmissionHandler = fn;
	};
	form.setResponseHandler = function(fn) {
		this.responseHandler = fn;
	};
	return form;
};
Expo.AJAXForm.sendForm = function() {
	if (this.beforeSubmissionHandler.call(this) !== false) {
		var fields = this.elements;
		var parameters = "";
		for (var i = 0, il = fields.length, field, type, isSelect; i < il; i++) {
			field = fields[i];
			type = field.getAttribute("type");
			isSelect = /select/i.test(field.nodeName);
			if (field.getAttribute("name") && (/text|hidden|password|submit|image/i.test(type) || isSelect || (/radio|checkbox/i.test(type) && field.checked) || /textarea/i.test(field.nodeName))) {
				parameters += field.getAttribute("name") + "=" + encodeURIComponent(((isSelect)? field.options[field.selectedIndex].value : field.value)) + "&";
			}
		}
		parameters += "mode=ajax";
		this.ajax({
			url : this.getAttribute("action"),
			method: "POST",
			params : parameters.replace(/&*$/g, ""),
			callback : this.responseHandler,
			headers : this.headers || {}
		});
	}
	return false;
};


Expo.slideshow = function() {
	var show = function($nav) {
		var no = $nav.data("no");
		var $container = $nav.parent().parent();
		$nav.addClass("active");
		$container.find("div").eq(0).animate({"marginLeft": -($container.innerWidth() * no) + "px"}, 250, "easeInOutQuart");
		$container.find(".timeline-navigation").slider("option", "value", no + 1);
		$nav.siblings().removeClass("active");		
	};
	var move = function($nav, forward) {
		var $container = $nav.parent().parent();
		var no = $container.data("no");
		if (no == null) {
			no = 0;
		}
		var noOfItems = $container.find(".image").length;
		if (forward) {
			if (no + 1 < noOfItems) {
				no = no + 1;
			}
		} else {
			if (no > 0) {
				no = no - 1;
			}
		}
		$container.data("no", no);
		$container.find("div").eq(0).animate({"marginLeft": -($container.innerWidth() * no) + "px"}, 250, "easeInOutQuart", function(num, mnum) {
			return function() {
				var $next = $nav.parent().find(".button-next");
				var $previous = $nav.parent().find(".button-previous");
				if (num + 1 === mnum) {
					$next.animate({"opacity": ".5"}, 100);
					$next.css({"cursor": "default"});
				}
				if (num === 0) {
					$previous.animate({"opacity": ".5"}, 100);
					$previous.css({"cursor": "default"});
				}
				if (num > 0) {
					$previous.css({"opacity": "1", "cursor": "pointer"});
				}
				if (num <= 0) {
					$next.css({"opacity": "1", "cursor": "pointer"});
				}
			};
		}(no, noOfItems));
	};
	var DOMReady = function() {
		var $slideshows = $(".slideshow");
		for(var i = 0; i < $slideshows.length; i++) {
			var $slideshow = $($slideshows[i]);
			$slideshow.find("ul").wrap($("<div></div>").attr("id", "slideshow-" + i));
			var $slides = $slideshow.find("li");
			var maxWidth = 0;

			var $nav = $("<ul></ul>").addClass("slideshow-navigation");
			
			// check to see if we're using a timeline navigation
			$nav.timeline = $slideshow.hasClass("timeline") ? true : false;
			$nav.numeric = $slideshow.hasClass("numeric") ? true : false;

			$slides.each(function(j) {
				var $slide = $(this);
				$slide.data("no", j);
				maxWidth = maxWidth + $slide.outerWidth();
				$slide.css({
					"float": "left",
					"width": $slide.width(),
					"visibility": "visible"
				});
				
				// adding navigation
				var $navEl;
				if ($nav.timeline) {
					$navEl = $("<li>" + $slide.find("h3").text() + "</li>").data("no", j);
					if (j == 0) {
						$navEl.addClass("active");
					}
					$nav.append($navEl);
				} else if ($nav.numeric){
					$navEl = $("<li>" + (j + 1) + "</li>").data("no", j);
					if (j == 0) {
						$navEl.addClass("active");
					}
					$nav.append($navEl);
				}				
			});

			$slideshow.find("ul").css({
				"overflow": "hidden",
				"width": maxWidth
			});

			$slideshow.append($nav);

			if ($nav.timeline) {
				var iWidth = (maxWidth / $slides.length)
				$slideshow.append($("<div></div>").addClass("timeline-navigation").slider({
					"min": 1,
					"max": $slides.length,
					"value": 1,
					"step": 1,
					"slide": function(e, ui) {
						var no = (ui.value - 1);
						var $container = $(ui.handle).parent().parent();
						var $el = $container.find("div").eq(0);
						$el.stop();
						$el.animate({"marginLeft": -(iWidth * no) + "px"}, 400, "easeOutQuart");
						$container.find(".slideshow-navigation li").each(function(e) {
							$navEl = $(this);
							$navEl.removeClass("active");
							if ($navEl.data("no") == no) {
								$navEl.addClass("active");
							}
						});
					}
				}));
			}
			
			if (!$nav.timeline && !$nav.numeric) {
				$previous = $("<li class=\"button button-previous\">bakåt</li>").css({"cursor": "default", "opacity": ".5"}).bind("click", function(e) {
					e.preventDefault();
					move($(this), false);
				});
				$next = $("<li class=\"button button-next\">framåt</li>").bind("click", function(e) {
					e.preventDefault();
					move($(this), true);
				});
				$nav.append($previous);
				$nav.append($next);
			} else {
				$("ul.slideshow-navigation li").live("click", function() {
					show($(this));
					return false;
				});
			}
		}
	};

	return {
		init: function() {
			$(document).ready(DOMReady);
		}
	};
}();


Expo.calendar = function() {
	var months = ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"];
	return {
		init: function() {
			if ($("DIV.calendar-teaser").length > 0) {
				window.showCalendar = Expo.calendar.show;
				document.write("<script type=\"text/javascript\" src=\"http://upcoming.yahoo.com/services/rest?api_key=3c1a2fe0ab&format=json&method=group.getEvents&group_id=16781&eventsPerPage=10&callback=showCalendar\"></script>");			
			}
		},
		show: function(data) {
			if (data || (data.length && data.length == 0)) {
				if (data.rsp && data.rsp.event) {
					var events = data.rsp.event;
					var noOfEvents = events.length;
					if (noOfEvents > 0) {
						var html = new Expo.StringBuffer();
						for (var i = 0; i < noOfEvents; i++) {
							html.append("<li class=\"vevent\"><h3><a href=\"http://upcoming.yahoo.com/event/").append(events[i].id).append("\">").append(events[i].name).append("</a></h3>");
							if (events[i].venue_name || events[i].description) {
								html.append("<p>");
								if (events[i].venue_name) {
									html.append("<span class=\"location\">").append(events[i].venue_name).append("</span>\n");
								}
								if (events[i].description) {
									html.append("<span class=\"summary\">").append(events[i].description).append("</span>");
								}
								html.append("</p>");
							}
							var dateTag = "abbr";
							/*@cc_on
							if (@_jscript_version==5.6 ||
								(@_jscript_version==5.7 && 
								navigator.userAgent.toLowerCase().indexOf("msie 6.") != -1)) {
							   	dateTag = "div";
							}
							@*/
							var date = new Date(parseInt(events[i].start_date.substring(0,4), 10), parseInt(events[i].start_date.substring(5,7), 10) - 1, parseInt(events[i].start_date.substring(8,10), 10));
							html.append("<").append(dateTag).append(" class=\"dtstart\" title=\"").append(events[i].start_date).append("\">");
							html.append("<span class=\"month\">").append(months[date.getMonth()]).append("</span>");
							html.append("<span class=\"day\">").append(date.getDate()).append("</span>");
							html.append("</").append(dateTag).append(">");
							html.append("</li>");
						}
						var $ul = $("<ul></ul>");
						$ul.hide();
						$ul.html(html.toString());
						var $teaser = $("DIV.calendar-teaser");
						var $content = $teaser.children();
						$content.append($ul);
						$teaser.removeClass("is-loading");
						$ul.fadeIn(300);
					}
				}
			} else {
				$("DIV.calendar-teaser").remove();
			}
		}
	};
}();


Expo.siteSearch = function() {
	
	var resultContainer = "<a name=\"setop\"></a><div id=\"cse\" class=\"search-result\"></div>";
	var resultTemplate = "<div style=\"display:none;\"><div id=\"expo_webResult\"><div class=\"search-result-content\"><h2><a class=\"gs-title\" data-attr=\"{href:unescapedUrl}\" data-body=\"html(title)\"></a></h2><p data-body=\"html(content)\"></p></div></div></div>";
	var loop = 0;
	
	var loadSiteSearch = function() {
		google.load("search", "1", {
			language: "sv",
			nocss: true,
			callback: function() {
				customSearchControl = new google.search.CustomSearchControl("001912513585125312607:csvl-myh56m");
				customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
				customSearchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
				/*
				var options =  new google.search.SearcherOptions();	
				options.setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN);
				customSearchControl.addSearcher(new google.search.WebSearch(), options);
				*/
				
				var options = new google.search.DrawOptions();
				options.setSearchFormRoot("cse-search-form");
				options.setAutoComplete(true);
				options.setDrawMode(google.search.SearchControl.DRAW_MODE_LINEAR);
				
				// Add our own structure to the result
				google.search.Csedr.addOverride("expo_");
				
				// Bind the search control
				customSearchControl.draw("cse", options);
				
				// Add on search complete event
				customSearchControl.setSearchCompleteCallback(this, searchComplete);
				searchstring = "Sökresultat för";
			}
		});
	};
	
	var searchComplete = function(sc, searcher) {
		var $resultHeader = $("#cse-resultHeader");
		if($resultHeader.length === 0) {
			$resultHeader = $("<div></div>").attr("id", "cse-resultHeader");
			$("#cse").prepend($resultHeader);
		}
		if(searcher.results.length > 0) {
			var startCount = (searcher.cursor.currentPageIndex * 10) + 1;
			var endCount = ((searcher.cursor.currentPageIndex + 1) * 10);
			var maxartiklar = searcher.cursor.estimatedResultCount;
			if(endCount >= searcher.cursor.estimatedResultCount) {
				endCount = endCount + (searcher.cursor.estimatedResultCount - endCount);
			}
			$resultHeader.html("<h1>"+searchstring+" <span>" + sc.input.value + "</span></h1><p class=\"result\">Visar " + startCount + "-" + endCount + " träffar. &nbsp;&nbsp;<a href=\"/sitesearch.php?searchtem="+ sc.input.value +"\">Avancerad s&ouml;kning</a>");
			$resultHeader.show();
			searchstring = "Sökresultat för";
		} else {
			//$resultHeader.hide();
			if (loop == 0)
			{
				loop = 1;
				customSearchControl.setSearchStartingCallback(
						  this,
						  function(control, searcher, query) {
						    searcher.setQueryAddition(searchterm);
						});
				customSearchControl.execute(searchterm);
			}
			else
			{
				$resultHeader.hide();
			}
		}
	}

	return  {
		init: function() {
			document.write("<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>");
			$(".page-content").prepend(resultTemplate + resultContainer);
			var maxIntervals = 1000;
			var wait = setInterval(function() {
				if (window.google || maxIntervals == 0) {
					clearInterval(wait);
					if (window.google) {
						loadSiteSearch();
					}
				}
				maxIntervals--;
			}, 10);
		},
		executesearch: function(searchterm) {
			document.location.hash = "#setop";
			searchstring = "Artiklar taggade med";
			customSearchControl.execute(searchterm);
		},
		executesearchae: function(searchterm) {
			document.location.hash = "#setop";
			searchstring = "Artiklar taggade med";
			customSearchControl.setSearchStartingCallback(
					  this,
					  function(control, searcher, query) {
					    searcher.setQueryAddition('more:pagemap:document-keywords:'+searchterm);
					});
			customSearchControl.execute(searchterm);
		}
	};
}();

function str_replace (search, replace, subject, count) {
    // Replaces all occurrences of search in haystack with replace  
    // 
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/str_replace    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Gabriel Paderni
    // +   improved by: Philip Peterson
    // +   improved by: Simon Willison (http://simonwillison.net)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)    // +   bugfixed by: Anton Ongson
    // +      input by: Onno Marsman
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    tweaked by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   input by: Oleg Eremeev
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Oleg Eremeev
    // %          note 1: The count parameter must be passed as a string in order    // %          note 1:  to find a global variable in which the result will be given
    // *     example 1: str_replace(' ', '.', 'Kevin van Zonneveld');
    // *     returns 1: 'Kevin.van.Zonneveld'
    // *     example 2: str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
    // *     returns 2: 'hemmo, mars'    var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
            f = [].concat(search),
            r = [].concat(replace),
            s = subject,
            ra = r instanceof Array, sa = s instanceof Array;    s = [].concat(s);
    if (count) {
        this.window[count] = 0;
    }
     for (i=0, sl=s.length; i < sl; i++) {
        if (s[i] === '') {
            continue;
        }
        for (j=0, fl=f.length; j < fl; j++) {            temp = s[i]+'';
            repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
            s[i] = (temp).split(f[j]).join(repl);
            if (count && s[i] !== temp) {
                this.window[count] += (temp.length-s[i].length)/f[j].length;}        }
    }
    return sa ? s : s[0];
}

Expo.init();
