/*
 * OSUIT The Next Generation
 * Homepage JavaScript
 *
 * (C) 2010 OSU Institute of Technology
 * 
 * Programmers:
 * Keith Gable <keith.gable@okstate.edu>
 */

// This object represents the modal panel that shows up on the page.
var HomepagePanel = {
    mouseleave: function(event) {
	if (debug) console.debug("[HomepagePanel(1)] Closing panel via mouseleave.")
	$("hpmodal").fade({ duration: 0.2 });
    },
    click: function(event) {
	if (event.findElement("div#hpmodal-panel") == undefined) {
	    if (debug) console.debug("[HomepagePanel(1)] Closing panel via click.")
	    $("hpmodal").fade({ duration: 0.2 });
	}
    },
    show: function(tileId_or_UriFragment) {
	if (debug) console.debug("[HomepagePanel(1)] Showing homepage panel");

	// Empty the tile of all child elements
	while ($("hpmodal-panel").childNodes.length >= 1) {
	    $("hpmodal-panel").removeChild($("hpmodal-panel").firstChild);
	}
	
	var panel_top = 110 - document.viewport.getScrollOffsets().top; // scroll top will normally be 0.
	$("hpmodal-panel").setStyle({ textAlign: "center", top: panel_top + "px" });

	// Create and insert the progress indicator. Not using innerHTML because it
	// is a nonstandard method that is not XML compatible. Though it would work.
	var progress_indicator = document.createElement("progress");
	Element.addClassName(progress_indicator, "indeterminate");
	Element.writeAttribute(progress_indicator, "id", "hpmodal-panel-progress-indicator");
	Element.writeAttribute(progress_indicator, "value", 0);
	Element.writeAttribute(progress_indicator, "max", 1);

	progress_indicator.appendChild(document.createTextNode("Loading..."));
	if (debug) progress_indicator.appendChild(document.createTextNode(" [" + tileId + "]"));

	// Insert the progress indicator into the DOM.
	$("hpmodal-panel").appendChild(progress_indicator);

	// show the modal window.
	$("hpmodal").appear({ duration: 0.2 });

	var loading_top = parseFloat($("hpmodal-panel").getStyle("height")) / 2;
	$("hpmodal-panel-progress-indicator").setStyle({ position: "relative", top: loading_top + "px" });

	// Do an Ajax call here to grab the panel...

	// If the +tileId_or_UriFragment+ starts with /, we know
	// to just request the URI fragment.
	var uri_fragment = /^\//.test(tileId_or_UriFragment);
	var req_uri = "";
	if (uri_fragment) {
	    req_uri = tileId_or_UriFragment;
	} else {
	    var reqTile = tileId_or_UriFragment.substring(3); // removes "hp-" from the ID.
	    req_uri = "/tile_groups/1/tiles/" + reqTile;
	}
	
	new Ajax.Updater({ success: "hpmodal-panel" }, req_uri, {
		method: "get",
		evalScripts: true,
		onSuccess: function() {
		    if ($("hpmodal-panel-progress-indicator")) $("hpmodal-panel-progress-indicator").hide();
		    $("hpmodal-panel").setStyle({ textAlign: "left" });
		},
		onFailure: function() {
		    if ($("hpmodal-panel-progress-indicator")) {
			$("hpmodal-panel-progress-indicator").setStyle({ backgroundImage: "none" });
			$("hpmodal-panel-progress-indicator").textContent = "Error loading page. Please try again.";
		    }
		}
	});

	// hook up the mouseleave handler.
	$("hpmodal-panel").observe("mouseleave", HomepagePanel.mouseleave);
	$("hpmodal").observe("click", HomepagePanel.click);
    }
}

// Handles the news, videos, photos, and events buttons.
var HomepageSections = {
    carouselbox_state: 0, // 0 = hidden, 1 = animating, 2 = visible
    carouselbox_content: null, // news or photos
    // Called when the DOM is initialized and hooks the buttons.
    init: function() {
	document.observe("mouseover", HomepageSections.mouseover);
    },
    // Called when the mouse goes over a section button or the carouselbox.
    mouseover: function(event) {
	var button = event.findElement("#sections ul li");
	var carouselbox = event.findElement("#carouselbox-inside");

	// check that this event even pertains to this function.
	if (button || carouselbox) {
	    // check for and load the different views for buttons.
	    if (button) {
		if (button.getAttribute("id") == "sections-news") {
		    HomepageSections.load_carouselbox("news");
		    HomepageSections.show_carouselbox();
		} else if (button.getAttribute("id") == "sections-photos") {
		    HomepageSections.load_carouselbox("photos");
		    HomepageSections.show_carouselbox();
		} else if (button.getAttribute("id") == "sections-videos") {
		    // This shows as a modal box.
		    HomepagePanel.show("/media/");
		} else if (button.getAttribute("id") == "sections-events") {
		    // This also shows as a modal box.
		    HomepagePanel.show("/calendar/");
		}
	    }
	    
	} else {
	    HomepageSections.hide_carouselbox();
	}
    },
    // Loads the carousel box with data.
    load_carouselbox: function(content) {
	if (content != HomepageSections.carouselbox_content) {
	    if (content == "news") {
		new Ajax.Updater("carouselbox-inside", "/news_stories", {
			method: "get",
			evalScripts: true,
			onComplete: function() {
			    // initialize the carousel. called on a delay.
			    new PeriodicalExecuter(function(pe) {
				if (window.NewsStoriesCarousel) window.NewsStoriesCarousel.init();
				pe.stop();
			    }, 0.1);
			}
		});
		HomepageSections.carouselbox_content = "news";
	    } else if (content == "photos") {
		new Ajax.Updater("carouselbox-inside", "/news_photos", {
			method: "get",
			evalScripts: true,
			onComplete: function() {
			    // initialize the carousel. called on a delay.
			    new PeriodicalExecuter(function(pe) {
				if (window.NewsPhotosCarousel) window.NewsPhotosCarousel.init();
				pe.stop();
			    }, 0.1);
			}
		});
		HomepageSections.carouselbox_content = "photos";
	    }
	}
    },
    // Call this to show the carousel box.
    show_carouselbox: function() {
	if ($("carouselbox") && HomepageSections.carouselbox_state == 0) {
	    HomepageSections.carouselbox_state = 1;
	    $("carouselbox").show();
	    HomepageSections.carouselbox_state = 2;
	}
    },
    // Call this to hide the carousel box.
    hide_carouselbox: function() {
	if ($("carouselbox") && HomepageSections.carouselbox_state == 2) {
	    HomepageSections.carouselbox_state = 1;
	    $("carouselbox").hide();
	    HomepageSections.carouselbox_state = 0;
	    HomepageSections.carouselbox_content = null;
	}
    }
}

// Functions that affect the entire homepage and start any other processes that
// need to run for the homepage to run properly.
var Homepage = {
    // Called when the DOM is initialized.
    init: function() {
	// turn on the tiles div
	$$("div.tiles").first().show();
	new HomepageSlices($$("div.tiles").first(), 0.125);

	// make the tile links render on the image tiles if the browser has JavaScript.
	if ($("tiles")) $("tiles").addClassName("tiles");

	// Hook homepage events.
	Homepage.init_tiles();

	// Hook homepage section events.
	HomepageSections.init();

	// Run the resize handler to initialize sizes.
	Homepage.resize();
    },
    // Called when the page finishes loading. Sets up parts of the homepage that
    // won't initialize properly until the images exist.
    init_loaded: function() {
	// Create the homepage modal box.
	var modal = document.createElement("div");
	var modal_panel = document.createElement("div");
	
	// Set IDs and other attributes so the hpmodal gets styled properly.
	Element.writeAttribute(modal, "id", "hpmodal");
	Element.setStyle(modal, { display: "none" });
	Element.writeAttribute(modal_panel, "id", "hpmodal-panel");

	// Create and identify the homepage carousel box.
	var carousel_box = document.createElement("div");
	var carousel_box_inside = document.createElement("div");
	Element.writeAttribute(carousel_box, "id", "carouselbox");
	Element.setStyle(carousel_box, { display: "none" });
	Element.writeAttribute(carousel_box_inside, "id", "carouselbox-inside");

	// Append the carousel box inside to the carousel box.
	carousel_box.appendChild(carousel_box_inside);

	// Append the panel to the modal window.
	modal.appendChild(modal_panel);

	// Append this to the bottom of the page.
	$$("body").first().appendChild(modal);
	$$("body").first().appendChild(carousel_box);

	// Run the resize handler again once the page is loaded.
	Homepage.resize();
    },
    // Called when the tiles need to be initialized.
    init_tiles: function() {
	$$("ul#tiles a").each(function(element) {
	    new HomepageTile(element);
	});
    },
    // called when the DOM is initialized, the page loads, and when the page is
    // resized.
    resize: function() {
	if (debug) console.debug("[Homepage(1)] Resize handler executing.");

	// Set the height of the tile links.
	$$("ul.tiles").first().setStyle({ height: $$("div.tiles img").first().getHeight() + "px" });

	// position the items below the homepage tiles.
	var sections = $("sections");
	var sections_top = 110 + $$("div.tiles img").first().getHeight(); // 110px is the top of the tile area.
	sections.setStyle({ position: "absolute", top: sections_top + "px" });

	var infoboxes = $("infoboxes");
	var infoboxes_top = sections_top + sections.getHeight() + 10;
	infoboxes.setStyle({ position: "absolute", top: infoboxes_top + "px" });

	var footer = $$("body>footer").first();
	var footer_top = infoboxes_top + infoboxes.getHeight();
	footer.setStyle({ position: "absolute", width: "100%", top: footer_top + "px", margin: "1.5em 0 0 0" });

	// Resize the hpmodal-panel.
	if ($("hpmodal-panel")) {
	    $("hpmodal-panel").setStyle({
		width: ((document.viewport.getWidth() * 0.8) - 80) + "px", // 80 = both margins
		height: ($$("div.tiles img").first().getHeight() - 90) + "px" // 90 = both margins + 10
	    });
	}
    }
}

// This represents the entire set of homepage tile images.
var HomepageSlices = Class.create({
    // slice_width is out of 1. 12.5% = 0.125
    initialize: function(container, slice_width) {
	this.container = $(container);
	this.slice_width = slice_width;
	this.resize();

	Event.observe(window, 'resize', this.resize.bindAsEventListener(this));
    },
    resize: function() {
	// Determine the pixel width represented by the percentage
	var pixel_width = Math.floor(this.slice_width * (document.viewport.getWidth() * 0.8));
	this.container.select("img").each(function(image) {
	   image.setStyle({ width: pixel_width + "px" });
	});
	this.container.setStyle({ height: this.container.select("img").first().getHeight() + "px" });
    }
});

// This represents a single homepage tile.
var HomepageTile = Class.create({
    initialize: function(element) {
	this.element = $(element);
	this.timer = null;
	this.mouse_status = 0; // 0 = mouse is out, 1 = mouse is over
	this.resize.bind(this).defer();

	Event.observe(this.element, 'click', this.click.bindAsEventListener(this));
	Event.observe(this.element, 'mouseenter', this.mouseenter.bindAsEventListener(this));
	Event.observe(this.element, 'mouseleave', this.mouseleave.bindAsEventListener(this));
	Event.observe(window, 'resize', this.resize.bindAsEventListener(this));
    },
    click: function(event) {
	this.mouse_status = 1;
	this.show(); // show the tile
	event.stop(); // prevents the link from doing its default action (navigation)
    },
    show: function() {
	if (this.mouse_status == 1) {
	    HomepagePanel.show(this.element.readAttribute("id"));
	}
	window.clearTimeout(this.timer);
	this.mouse_status = 0;
    },
    mouseenter: function(event) {
	// Set the mouse status and reset the timer.
	this.mouse_status = 1;
	if (this.timer) window.clearTimeout(this.timer);

	// Run show on a delay. (but bind this to show)
	this.timer = this.show.bind(this).delay(2.0);
    },
    mouseleave: function(event) {
	// Set the mouse status and reset the timer.
	this.mouse_status = 0;
	window.clearTimeout(this.timer);
    },
    resize: function(event) {
	// Determine the correct pixel width for the tile.
	var pixel_width = 0;
	var pixel_height = 0;
	var parent_node = $(this.element.parentNode);
	var tile_area_width = (document.viewport.getWidth() * 0.8);
	var tile_area_height = $$("div.tiles img").first().getHeight();
	var height_one = Math.floor(0.33 * tile_area_height);
	var height_two = Math.floor(0.65 * tile_area_height);

	if (parent_node.hasClassName("onexone")) {
	    pixel_width = Math.floor(0.125 * tile_area_width);
	    pixel_height = height_one;
	} else if (parent_node.hasClassName("onextwo")) {
	    pixel_width = Math.floor(0.125 * tile_area_width);
	    pixel_height = height_two;
	} else if (parent_node.hasClassName("twoxone")) {
	    pixel_width = Math.floor(0.25 * tile_area_width);
	    pixel_height = height_one;
	} else if (parent_node.hasClassName("twoxtwo")) {
	    pixel_width = Math.floor(0.25 * tile_area_width);
	    pixel_height = height_two;
	} else if (parent_node.hasClassName("threexone")) {
	    pixel_width = Math.floor(0.375 * tile_area_width);
	    pixel_height = height_one;
	} else if (parent_node.hasClassName("threextwo")) {
	    pixel_width = Math.floor(0.375 * tile_area_width);
	    pixel_height = height_two;
	} else if (parent_node.hasClassName("fourxone")) {
	    pixel_width = Math.floor(0.50 * tile_area_width);
	    pixel_height = height_one;
	} else if (parent_node.hasClassName("fourxtwo")) {
	    pixel_width = Math.floor(0.50 * tile_area_width);
	    pixel_height = height_two;
	} else {
	    console.debug(parent_node.inspect() + " has no valid class names");
	}
	
	parent_node.setStyle({ width: pixel_width + "px", height: pixel_height + "px" });
    }
});

// Events to hook
document.observe("dom:loaded", Homepage.init);
Event.observe(window, "load", Homepage.init_loaded);
Event.observe(window, "resize", Homepage.resize);