// ==ClosureCompiler==
// @output_file_name aluko-common.min.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// @externs_url http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js
// @externs_url http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.js
// @externs_url http://www.aluko.no/js/jquery.timers-1.2.js
// ==/ClosureCompiler==
/** @fileoverview
 * This is a common script for all pages. It performs various compability adjustments,
 * as well as adjusting size and positioning of variable size images.
 */

$('#loadOverlay').ready(function(){
	$("#loadOverlay img").css({
		"margin-top":($(window).height()/2 - 16)
	});
	$('#loadOverlay').show();
	
	});

$(main);

/**
 * The main functionality for the page.
 */
function main(){	
	setUpMenus();
	
	/**
	 * When the header image is completly loaded, trigger the layout adjustments.
	 */
    $("header img").load(layout).each(function(){
        if (this.complete || (jQuery.browser.msie && jQuery.browser.version === 6)) {
            $(this).trigger("load");
        }
    });
    
	/**
	 * Whenever we resize the window, we have to adjust the top and bottom
	 * of the #body-section, as well as readjusting image sizes and positions
	 */
    $(window).resize(layout);
    
	setUpImagescrolls();
	
	/**
	 * Adjusts the touch events on #body-section so we can scroll it with a single 
	 * touch, and not double touch as default on iPhone.
	 */
    $("#body-section .middle").bind('touchstart', function(event){
        if ($(this).is("[data-touchscroll]")) {
            $(this).removeAttr("data-touchscroll");
        }
        else {
            $(this).attr("data-touchscroll", event.originalEvent.targetTouches[0].pageY);
        }
    });
    $("#body-section .middle").bind('touchmove', function(event){
        event.preventDefault();
        if ($(this).is("[data-touchscroll]")) {
            var py = event.originalEvent.targetTouches[0].pageY;
            var dpy = $(this).attr("data-touchscroll") - py;
            $(this).attr("data-touchscroll", py);
            $(this).scrollTop($(this).scrollTop() + (dpy));
        }
    });
    $("#body-section .middle").bind('touchend', function(event){
        if ($(this).is("[data-touchscroll]")) {
            $(this).removeAttr("data-touchscroll");
        }
        $(this).scroll();
    });
	
}

/**
 * Adjusts the layout of the page. The \#body-section is adjusted so it's top 
 * and bottom aligns with the header and footer. All images with 
 * a @a data-fullsrc attribute are resized (recropped) and repositioned to 
 * fit better on the page.
 */
function layout() {
        $("#body-section").css("top", $("header").outerHeight());
        $("#body-section").css("bottom", $("footer").parent().innerHeight() - $("footer").position().top);
        
	var q = $.jqmq({
		delay: 240,
		batch: 1,
		callback: function( img ) {
			var jImg = $(img);
			setImageSizes(jImg);
	   	        setImagePosition(jImg);
		}
	});

        $("img[data-fullsrc]").jqmqAddEach(q);
	$("#loadOverlay").fadeOut();
}

/**
 * Sets up the hover menu in the header.
 */
function setUpMenus(){
    // Hide all submenus
    $("nav > menu menu, header > table table").hide();
    
    // Show submenus when hovering
    $("nav > menu > li, header > table tr > td").each(function(){
        $(this).hover(        
        function(){ //< Mouse hovers over object.
            var jqMenu = $("menu, table", this);
            jqMenu.css("width", $(this).width());
            var jqParent = jqMenu.parent();
            var posParent = jqParent.position();
            jqMenu.css("left", posParent.left);
            jqMenu.css("top", posParent.top + jqParent.outerHeight());
            
            jqMenu.show();
			//jqMenu.fadeIn();
            
        },        
        function(){ //< Mouse hover leaves object.
            $("menu, table", this).hide();
			//$("menu, table", this).fadeOut();
        });
    });
	/**
	 * The hover effects we add interfers with the normal hover effect, so we simulate it manually.
	 */
    $("nav > menu > li, header > table tr > td, nav > menu a, header > table a").each(function(){
        $(this).hover(function(){
            $(this).addClass("hover");
        }, function(){
            $(this).removeClass("hover");
        });
    });
}

/**
 * Sets up the horizontal image scrolling marquees. These automatically scroll 
 * in a loop, and can be panned by hovering over the left and right side. 
 * On a touch display, they can be swiped left/right.
 * 
 * @todo add arrows to the panners
 * @todo this is spesific behaviour only used by some pages, and 
 * should be moved to it's own script 
 */
function setUpImagescrolls(){
    var imagescrolls = $("#project ul, #projects ul");
    
    imagescrolls.everyTime("4s", "marquee", horizontalMarquee);
    imagescrolls.css("overflow", "hidden");
    imagescrolls.hover(function(){
        $(this).stopTime("marquee");
    }, function(){
        $(this).everyTime("4s", "marquee", horizontalMarquee);
    });
    
    var leftpan = $("<div id='leftpan'><img src='images/img-viewer/left-arrow.png' alt='Left' width='48' height='48' style='margin-top: 40px'/></div>");
    leftpan.css({
        'position': 'absolute',
        'top': 0,
        'left': 0,
        'width': '64px',
		'height': '128px',
		'text-align':'center'
    });
	leftpan.css("background-color", Modernizr.rgba ? "rgba(0,0,0,0.25)" : "rgb(192,192,192)");
    leftpan.appendTo(imagescrolls);
    leftpan.hover(function(){
        var parent = $(this).parent();
        parent.animate({
            'scrollLeft': '-=32'
        }, 500, "easeInQuad");
        parent.everyTime(500, "panleft", function(){
            $(this).animate({
                'scrollLeft': "-=64"
            }, 500, "linear");
        });
    }, function(){
        $(this).parent().stopTime("panleft");
    });
    
    var rightpan = $("<div id='rightpan'><img src='images/img-viewer/right-arrow.png' alt='Right' width='48' height='48' style='margin-top: 40px'/></div>");
    rightpan.css({
        'position': 'absolute',
        'top': 0,
        'right': 0,
        'width': '64px',
		'height': '128px',
		'text-align':'center'
    });
	rightpan.css("background-color", Modernizr.rgba ? "rgba(0,0,0,0.25)" : "rgb(192,192,192)");
    rightpan.appendTo(imagescrolls);
    rightpan.hover(function(){
        var parent = $(this).parent();
        parent.animate({
            'scrollLeft': "+=32"
        }, 500, "easeInQuad");
        parent.everyTime(500, "panright", function(){
            $(this).animate({
                'scrollLeft': "+=64"
            }, 500, "linear");
        });
    }, function(){
        $(this).parent().stopTime("panright");
    });
    
    imagescrolls.bind('touchstart', function(event){
        if ($(this).is("[data-touchscroll]")) {
            $(this).removeAttr("data-touchscroll");
        }
        else {
            $(this).attr("data-touchscroll", event.originalEvent.targetTouches[0].pageX);
        }
    });
    imagescrolls.bind('touchmove', function(event){
        event.preventDefault();
        if ($(this).is("[data-touchscroll]")) {
            var newPageX = event.originalEvent.targetTouches[0].pageX;
            var scroll = $(this).attr("data-touchscroll") - newPageX;
            $(this).attr("data-touchscroll", newPageX);
            $(this).scrollLeft($(this).scrollLeft() + (scroll));
        }
    });
    imagescrolls.bind('touchend', function(event){
        if ($(this).is("[data-touchscroll]")) {
            $(this).removeAttr("data-touchscroll");
        }
        $(this).scroll();
    });
}

/**
 * Scrolls the blocks in a list as a marquee
 * $this{Object}
 */
function horizontalMarquee(){
    var blocks = $(this).children("li");
    var blockWidth = blocks.outerWidth();
    var totalWidth = this.scrollWidth;
    var maxScroll = totalWidth - $(this).innerWidth();
    var scroll = $(this).scrollLeft();
    var scrollTo = floorN((scroll < maxScroll) ? scroll + blockWidth : 0, blockWidth);
    $(this).animate({
        'scrollLeft': scrollTo
    }, "slow");
}

/**
 * Sets the size of images to screen size.
 * @param{Object} image an jQuery object containing an image object
 */
function setImageSizes(image){

    var parent = image.parents().filter(function(){
        return $(this).css("display") == "block";
    });
    var vars = $.parseJSON(image.attr("data-phpThumb"));
    vars.src = image.attr("data-fullsrc");
    var parentWidth = parent.innerWidth();
    var parentHeight = parent.innerHeight();
    
    if ($(parent).is(".left-float, .right-float")) {
        parentHeight = parent.eq(1).innerHeight();
        parent.eq(0).css("height", parentHeight);
    }
    if (!image.is("[src$='.svg']")) {
        vars.w = ceilN(parentWidth, 64);
        vars.h = ceilN(parentHeight, 64);
        image.css({
            "width": vars.w,
            "height": vars.h
        });
        
        var url = thumbUrl(vars);
        image.attr("src", url);
    }
    else {
        image.css({
            "width": parentWidth,
            "height": parentHeight
        });
    }
}

/**
 * Centers an image in a block.
 * @param{Object} image an jQuery object containing an image object
 */
function setImagePosition(image){

    var parent = image.parents().filter(function(){
        return $(this).css("display") == "block";
    });
    var parentWidth = parent.innerWidth();
    var parentHeight = parent.innerHeight();
    
    var width = image.width();
    var height = image.height();
    
    var scaleW = parentWidth ? parentWidth / width : 0;
    var scaleH = parentHeight ? parentHeight / height : 0;
    var scale = (image.attr("data-crop") == "outer") ? Math.min(scaleW, scaleH) : Math.max(scaleW, scaleH);
    
    var scaledWidth = Math.ceil(width * scale);
    var scaledHeight = Math.ceil(height * scale);
    
    image.css({
        "position": "absolute",
        "width": scaledWidth + "px",
        "height": scaledHeight + "px",
        "top": (parentHeight - scaledHeight) / 2 + "px",
        "left": (parentWidth - scaledWidth) / 2 + "px"
    });
}

/**
 * Returns the nearest multiple of N.
 * @param{number} i number to find multiple of
 * @param{number} n N
 * @return{number} multiple of N
 */
function roundN(i, n){
    return Math.round(i / n) * n;
}

/**
 * Returns the multiple of N that's greater than or equal to a number.
 * @param{number} i number to find multiple of
 * @param{number} n N
 * @return{number} multiple of N
 */
function ceilN(i, n){
    return Math.ceil(i / n) * n;
}

/**
 * Returns the multiple of 8 that's lower than or equal to a number.
 * @param{number} i number to find multiple of
 * @param{number} n N
 * @return{number} multiple of N
 */
function floorN(i, n){
    return Math.floor(i / n) * n;
}

/**
 * Returns the phpThumb URL for a given set of variables
 * @param{Object} vars An object containing the variables
 * @return{string} phpThumb URL
 */
function thumbUrl(vars){
    vars.src = "../" + vars.src;
    return "libs/phpThumb.php?" + $.param(vars);
}

