// build/photoviewer_base.js
// set up short cuts into the global namespace
var lib = {};
lib.d = YAHOO.util.Dom;
lib.e = YAHOO.util.Event;
lib.ce = YAHOO.util.CustomEvent;
lib.a = YAHOO.util.Anim;
// photoviewer base object
YAHOO.namespace("YAHOO.photoViewer");
// instance object
YAHOO.photoViewer.base = function(id){
	// dom
	var container = null; // thumb container
	var viewerDom = null;
	var maskDom = null; // overlay (viewer) mask
	var showcaseImage = null;
	var headerDom = null;
	var titleDom = null;
	var closeDom = null;
	var bodyDom = null;
	var descDom = null;
	var footerDom = null;
	var prevDom = null;
	var nextDom = null;
	// yui objects
	var viewer = null;
	// collections
	var thumbs = null; // collection of thumbs in thumb container
	// storage
	var that = this;
	var properties = YAHOO.photoViewer.config.viewers[id].properties;
	var events = {}; // storage for custom events
	var currentThumb = null;
	var preloadtimer = null;
	var preloadimgs = [];
	var hasLoaded = {};
	var defaultText = {next:"next", prev:"prev", close:"close"};

	// public
	this.init = function(){
		// check loadfrom
		if (properties.loadFrom == "xml"){
			setEvents();
		}
		if (properties.loadFrom == "html"){
			config();
		}
		return this;
	}; // load init
	this.loadXML = function(url){
		var sUrl = url ? url : properties.url;
		var postData = "";
		var callback = {
		  success: readPhotos,
		  failure: fail,
		  that: this
		};
		YAHOO.photoViewer.loading.on();
		var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback, postData);
	}; // end loadXML
	this.prev = function(){
		var prevSibling = lib.d.getPreviousSiblingBy(currentThumb.parentNode, testForThumb);
		if (!prevSibling){
			prevSibling = thumbs[0];
		}
		currentThumb = prevSibling.getElementsByTagName("img")[0];
		loadViewer(prevSibling);
	}; // end prev
	this.next = function(){
		var nextSibling = lib.d.getNextSiblingBy(currentThumb.parentNode, testForThumb);
		if (!nextSibling){
			nextSibling = thumbs[thumbs.length - 1];
		}
		currentThumb = nextSibling.getElementsByTagName("img")[0];
		loadViewer(nextSibling);
	}; // end next
	this.close = function(){
		viewer.hide();
		lib.d.setStyle(maskDom, "visibility", "hidden");
	}; // end close
	this.open = function(index){
		var thumb = currentThumb ? currentThumb.parentNode : thumbs[0];
		var index = Number(index);
		if (index > -1 && index < thumbs.length){
			thumb = thumbs[index];
		}
		currentThumb = thumb.getElementsByTagName("img")[0];
		loadViewer(thumb);
		viewer.show();
	}; // end open
	this.on = function(evt, callback){
		events[evt].subscribe(callback);
	}; // end on
	this.un = function(evt, callback){
		events[evt].unsubscribe(callback);
	}; // end on
	this.getProperty = function(p){
		if (!properties[p]){ return null; }
		return properties[p]
	}; // end getProperty
	this.setProperty = function(p, v){
		if (!properties[p]){ return null; }
		properties[p] = v;
		return properties[p]
	}; // end getProperty
	// private
	/* -----------------------------*/
	/* -----------------------------*/
	function getThumbIndex(el){
		for (var a = 0; a < thumbs.length; a++){
			if (el === thumbs[a])
				return a;
		}
	}; // end getThumbIndex
	function loadViewer(e){
		if (!viewer){
			createViewer();
			if (YAHOO.env.ua.ie == 0 || YAHOO.env.ua.ie == 7) { lib.e.on(showcaseImage, "load", viewerLoaded); }
			else { that.checkLoadForIe(); }
		}
		var thumbImage = lib.e.getTarget(e) ? lib.e.getTarget(e) : e.getElementsByTagName("img")[0];
		var thumbAnchor = thumbImage.parentNode;
		//var titleText = thumbAnchor.getAttribute("title").length ? thumbAnchor.getAttribute("title") : "";
		//var descText = thumbImage.getAttribute("alt").length ? thumbImage.getAttribute("alt") : "|";
		//var descText = thumbImage.getAttribute("alt");
		//var descText = thumbImage.getAttribute("alt");

		//insertStr(titleDom, titleText); // set header
		//insertStr(descDom.firstChild, descText); // set description
		showcaseImage.src = thumbAnchor.href;
		if (!hasLoaded[thumbAnchor.href]){ // check to see if this has loaded yet
			YAHOO.photoViewer.loading.on({applyTo:viewerDom});
		}
		/* set items hidden */
		lib.d.setStyle(bodyDom, "opacity", "0");
		lib.d.setStyle(titleDom, "opacity", "0");
		
		// adjust z indicies
		lib.d.setStyle(viewerDom, "z-index", YAHOO.photoViewer.zIndex++);
		lib.d.setStyle(maskDom, "z-index", YAHOO.photoViewer.zIndex - 1);
		// handle events
		if (!YAHOO.env.ua.ie != 0){ // everything but ie 6
			events.viewerupdated.unsubscribe(attachShowcaseEvts);
			events.viewerupdated.subscribe(attachShowcaseEvts);
			events.viewerupdated.fire();
		}
		else
			that.checkLoadForIe();
	}; // loadViewer
	function attachShowcaseEvts(){ // work around for ie bug
		if (!YAHOO.env.ua.ie == 0 || YAHOO.env.ua.ie == 7){ // for everything other than ie use load event for image
			lib.e.purgeElement(showcaseImage, true, "load");
			lib.e.on(showcaseImage, "load", viewerLoaded);
		}
		else{ // ie needs to use intervals and check the complete property
			checkLoadForIe();
		}
	}; 	// end attachShowcaseEvts

	/* bug for ie aaaaarrrrrggggghhhhhhhh!!!!!!!!!!!!! */
	var checkLoadTimeout = null;
	this.checkLoadForIe = function(){
		var func = "YAHOO.photoViewer.controller.getViewer('"+properties.id+"').checkLoadForIe()";
		if (checkLoadTimeout) {
			clearTimeout(checkLoadTimeout);
		}
		if (!showcaseImage.complete){
			checkLoadTimeout = setTimeout(func, 1000);
		}
		else{
			viewerLoaded();
		}
	}; // end checkLoad
	/* bug for ie aaaaarrrrrggggghhhhhhhh!!!!!!!!!!!!! */

	function getClassName(el){
		if (!typeof el == "object") { return null; }
		if (YAHOO.env.ua.ie)
			return el.getAttribute("className");
		else
			return el.getAttribute("class");
	}; // end getClassName
	function readPhotos(data){
		var photo = {};
		if(data.responseXML !== undefined){
			var photoNodes = data.responseXML.getElementsByTagName("photo");
			for (var i = 0; i < photoNodes.length; i++){
				photo.thumbsource = photoNodes[i].getElementsByTagName("thumbsource")[0].firstChild.nodeValue;
				photo.fullsource = photoNodes[i].getElementsByTagName("fullsource")[0].firstChild.nodeValue;
				if (photoNodes[i].getElementsByTagName("title")[0].firstChild){
					photo.title = photoNodes[i].getElementsByTagName("title")[0].firstChild.nodeValue;
				}
				else{
					photo.title = "";
				}
				if (photoNodes[i].getElementsByTagName("description")[0].firstChild){
					photo.description = photoNodes[i].getElementsByTagName("description")[0].firstChild.nodeValue;
				}
				else{
					photo.description = "";
				}
				createPhoto(photo);
			}
			events.xmlload.fire();
			config();
			YAHOO.photoViewer.loading.off();
		}
	}; // end readPhotos
	function fail(data){
		alert("XML file failed to load");
		YAHOO.photoViewer.loading.off();
	}; // end fail
	function createPhoto(photo){
		var anchor = document.createElement("a");
		var img = document.createElement("img");
		container = lib.d.get(properties.id);

		anchor.setAttribute("href", photo.fullsource);
		anchor.setAttribute("title", photo.title);
		lib.d.addClass(anchor, "photoViewer");
		//lib.d.setStyle(anchor, "display", "none"); // make the devs set thumbs to hidden via css

		img.setAttribute("src", photo.thumbsource);
		img.setAttribute("alt", photo.description);

		anchor.appendChild(img);
		container.appendChild(anchor);
	}; // end createPhoto
	function config(){
		container = lib.d.get(properties.id);
		thumbs = lib.d.getElementsByClassName("photoViewer", "a", container);
		//if (properties.preload){ // run preload routine
		//}
		that.preload();
		// set events
		setEvents();
	}; // end config
	this.preload = function(){
		var func = "YAHOO.photoViewer.controller.getViewer('"+properties.id+"').preload()";
		if (preloadtimer) {
			clearTimeout(preloadtimer);
		}
		for (var a = 0; a < thumbs.length; a++){
			preloadimgs.push(new Image());
			preloadimgs[a].src = thumbs[a].getAttribute("href");
		}
		if (preloadimgs.length < thumbs.length)
			preloadtimer = setTimeout(func, 1000);
	}; // end preload
	function setEvents(){
		if (thumbs){ // check if this viewer has  been configed
			// set thumb events, loop over collection
			for (var a = 0; a < thumbs.length; a++){
				lib.e.on(thumbs[a], "click", thumbClick, that, true);
			}
			// set window events
			lib.e.on(window, "resize", adjustPosition);
		}
		// set custom events
		if (!events.xmlload) events.xmlload = new lib.ce("xmlload", this, true, 1);
		if (!events.viewerload) events.viewerload = new lib.ce("viewerload", this, true, 1);
		if (!events.viewerupdated) events.viewerupdated = new lib.ce("viewerupdated", this, true, 1);
	}; // end setEvents
	function thumbClick(e, scope){
		currentThumb = lib.e.getTarget(e);
		loadViewer(e);
		lib.e.preventDefault(e); // stop default
	}; //  end thumbClick
	function viewerLoaded(){
		if (showcaseImage.src == "" || !showcaseImage.src){
			return;
		}
		// apply modal screen
		lib.d.setStyle(maskDom, "visibility", "visible");
		// record loaded
		hasLoaded[showcaseImage.src] = true;
		var widthTo = (lib.d.getRegion(showcaseImage).right - lib.d.getRegion(showcaseImage).left) +
			parseInt(lib.d.getStyle(imageContDom, "padding-left"), 10) +
			parseInt(lib.d.getStyle(imageContDom, "padding-right"), 10)
		;
		// show viewer
		if (!isVisible(viewerDom)){
			if (properties.fixedcenter){ // only grow if fixed center position
				lib.d.setStyle(viewerDom, "width", "10px");
				lib.d.setStyle(viewerDom, "height", "10px");
			}
			try{ viewer.center(); }catch(e) { /* bug in ie */ }
			viewer.show();
		}
		// ensure height by setting width
		lib.d.setStyle(descDom, "width", widthTo + "px");
		/* set total height for all components */
		var heightTo =
			lib.d.getRegion(showcaseImage).bottom - lib.d.getRegion(showcaseImage).top +
			parseInt(lib.d.getStyle(imageContDom, "padding-top"), 10) +
			parseInt(lib.d.getStyle(imageContDom, "padding-bottom"), 10) +
			lib.d.getRegion(descDom).bottom - lib.d.getRegion(descDom).top +
			lib.d.getRegion(headerDom).bottom - lib.d.getRegion(headerDom).top +
			lib.d.getRegion(footerDom).bottom - lib.d.getRegion(footerDom).top
		;
		var topTo = (lib.d.getViewportHeight()/2) - (heightTo/2) - 20 + lib.d.getDocumentScrollTop();
		if(topTo < 0) {
			topTo = 0;
		}
		var leftTo = (lib.d.getViewportWidth()/2) - (widthTo/2) - 20 + lib.d.getDocumentScrollLeft();
		var attr = {width:{to:widthTo},height:{to:heightTo},top:{to:topTo},left:{to:leftTo}};
		if (!properties.fixedcenter){ // dont update XY
			var x = eval(properties.xy)[0];
			var y = eval(properties.xy)[1];
			attr = {width:{to:widthTo},height:{to:heightTo}};
			lib.d.setStyle(viewerDom, "top", y + "px");
			lib.d.setStyle(viewerDom, "left", x + "px");
		}
		var resize = new lib.a(viewerDom, attr, properties.grow, properties.easing);
		resize.animate();
		resize.onComplete.unsubscribe(fadeViewer);
		resize.onComplete.subscribe(fadeViewer);
		// size mask
		adjustPosition();
		// clear objects
		resize = null;
		// fire event
		events.viewerload.fire();
		YAHOO.photoViewer.loading.off();
	}; // end viewerLoaded
	function fadeViewer(){
		var fade = null;
		//var domEls = [bodyDom, headerDom, footerDom];
		var domEls = [bodyDom,titleDom];

		for (var a = 0; a < domEls.length; a++){
			fade = new lib.a(domEls[a], {opacity:{to:1}}, properties.fade, properties.easing);
			fade.animate();
		}
		// clear objects
		fade = null;
	}; // end fade viewer
	function destroyViewer(){
		if (viewer){
			viewer.destroy();
		}
	}; // end destroyViewer
	function createViewer(){
		var buttonText = properties.buttonText ? properties.buttonText : defaultText;
		showcaseImage = document.createElement("img");
		lib.d.addClass(showcaseImage, "photoViewer-showcaseImage");
		lib.d.addClass(showcaseImage, "photoViewer-showcase");
		if (!viewerDom){
			// build viewer
			viewerDom = document.createElement("div");
			viewerDom.setAttribute("id", properties.id + "-viewer");
			lib.d.addClass(viewerDom, "photoViewer-viewer");
			// build mask
			maskDom = document.createElement("div");
			maskDom.setAttribute("id", properties.id + "-mask");
			lib.d.addClass(maskDom, "photoViewer-mask");
			lib.d.setStyle(maskDom, "z-index", YAHOO.photoViewer.zIndex - 1);
			// build header
			headerDom = document.createElement("div");
			headerDom.setAttribute("id", properties.id + "-header");
			lib.d.addClass(headerDom, "photoViewer-header");
			// build title
			titleDom = document.createElement("h1");
			titleDom.setAttribute("id", properties.id + "-title");
			lib.d.addClass(titleDom, "photoViewer-title");
			// build close button
			closeDom = document.createElement("a");
			var closeText = buttonText.close ? buttonText.close : defaultText.close;
			insertStr(closeDom, closeText);
			closeDom.setAttribute("id", properties.id + "-close");
			closeDom.setAttribute("href", "javascript:;");
			lib.d.addClass(closeDom, "photoViewer-close");
			lib.e.on(closeDom, "click", that.close);
			// build body
			bodyDom = document.createElement("div");
			bodyDom.setAttribute("id", properties.id + "-body");
			lib.d.addClass(maskDom, "photoViewer-body");
			// build image container
			imageContDom = document.createElement("div");
			imageContDom.setAttribute("id", properties.id + "-imageCont");
			lib.d.addClass(imageContDom, "photoViewer-imageCont");
			// build despription
			descDom = document.createElement("div");
			descDom.setAttribute("id", properties.id + "-desc");
			lib.d.addClass(descDom, "photoViewer-desc");
			// build footer
			footerDom = document.createElement("div");
			footerDom.setAttribute("id", properties.id + "-footer");
			lib.d.addClass(footerDom, "photoViewer-footer");
			// build buttons
			// prev
			prevDom = document.createElement("a");
			var prevText = buttonText.prev ? buttonText.prev : defaultText.prev;
			insertStr(prevDom, prevText);
			prevDom.setAttribute("id", properties.id + "-prev");
			prevDom.setAttribute("href", "javascript:;");
			lib.d.addClass(prevDom, "photoViewer-prev");
			lib.e.on(prevDom, "click", that.prev);
			// next
			nextDom = document.createElement("a");
			var nextText = buttonText.next ? buttonText.next : defaultText.next;
			insertStr(nextDom, nextText);
			nextDom.setAttribute("id", properties.id + "-next");
			nextDom.setAttribute("href", "javascript:;");
			lib.d.addClass(nextDom, "photoViewer-next");
			lib.e.on(nextDom, "click", that.next);
			// append nodes
			headerDom.appendChild(titleDom);
			headerDom.appendChild(closeDom);
			bodyDom.appendChild(imageContDom);
			imageContDom.appendChild(showcaseImage);
			bodyDom.appendChild(descDom);
			//descDom.appendChild(document.createElement("p")); // add paragraph
			footerDom.appendChild(prevDom);
			footerDom.appendChild(nextDom);
			if (properties.modal) { document.body.appendChild(maskDom); } // if modal switched on
			if (properties.position == "absolute"){
				document.body.appendChild(viewerDom);
			}
			else{
				lib.d.get(properties.container).appendChild(viewerDom);
			}
			// set up config
			// drag and drop
			if (properties.dragable){
				var dragObj = new YAHOO.photoViewer.DDOnTop(viewerDom.getAttribute("id"));
				dragObj.setHandleElId(titleDom.getAttribute("id"));
				lib.d.setStyle(titleDom, "cursor", "move");
				lib.e.on(viewerDom, "click", function(){
					lib.d.setStyle(this, "z-index", YAHOO.photoViewer.zIndex++);
				});
			}
		}
		var posXY = properties.xy ? properties.xy : null;
		var type, attr;
		if (properties.position == "absolute"){
			type = YAHOO.widget.Overlay;
			attr = {
				xy:eval(posXY),
				//fixedcenter:properties.fixedcenter,
				constraintoviewport:true,
				visible:false,
				zIndex:YAHOO.photoViewer.zIndex,
				effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:properties.fade}
			};
		}
		else{
			type = YAHOO.widget.Module;
			attr = {visible:true};
			// set up positioning
			lib.d.setStyle(viewerDom, "position", "relative");
		}
		viewer =  new type(properties.id + "-viewer", attr);
		viewer.setHeader(headerDom);
		viewer.setBody(bodyDom);
		viewer.setFooter(footerDom);
		viewer.render();
	}; // end createViewer
	function adjustPosition(){
		var width = (lib.d.getDocumentWidth() > lib.d.getViewportWidth()) ? lib.d.getDocumentWidth() : lib.d.getViewportWidth();
		var height = (lib.d.getDocumentHeight() > lib.d.getViewportHeight()) ? lib.d.getDocumentHeight() : lib.d.getViewportHeight();
		lib.d.setStyle(maskDom, "width", width + "px");
		lib.d.setStyle(maskDom, "height", height + "px");
	}; // end adjustPosition
	function isVisible(el){
		if (lib.d.getStyle(el, "visibility") == "visible")
			return true;
		else
			return false;
	}; // end isVisible
	function insertStr(el, str, append){
		var append = append ? append : false;
		if (!append && el.firstChild){
			el.removeChild(el.firstChild);
		}
		el.appendChild(document.createTextNode(str));
		//lib.d.setStyle(el, "height", lib.d.getRegion(el).bottom - lib.d.getRegion(el).top); // TODO: fix ie sizing issue
	}; // end insertStr
	function testForThumb(el){
		return lib.d.hasClass(el, "photoViewer");
	}; // end testForThumb
};
// loader class
YAHOO.photoViewer.loading = function(){
	var loadingScreen = null;
	var applyTo = null;
	var public = {
		on: function(config){
			/* config.applyTo = element to render loading over. */
			if (!config){ config = {}; }
			applyTo = config.applyTo ? lib.d.get(config.applyTo) : document.body;
			createLoadingScreen();
		},
		off: function(){
			lib.d.setStyle(loadingScreen, "display", "none");
		}
	};
	// private
	function createLoadingScreen(){
		if (!loadingScreen){
			loadingScreen = document.createElement("div");
			loadingScreen.setAttribute("id", "photoViewer-loading");
			lib.d.addClass(loadingScreen, "photoViewer-loading");
			lib.d.setStyle(loadingScreen, "position", "absolute");
			lib.d.setStyle(loadingScreen, "display", "none");
			document.body.appendChild(loadingScreen);
		}
		position();
		lib.d.setStyle(loadingScreen, "display", "block");
		lib.d.setStyle(loadingScreen, "z-index", YAHOO.photoViewer.zIndex + 10);
	}; // end createLoadingScreen
	function position(){
		lib.d.setStyle(loadingScreen, "top", lib.d.getRegion(applyTo).top + "px");
		lib.d.setStyle(loadingScreen, "left", lib.d.getRegion(applyTo).left + "px");
		lib.d.setStyle(loadingScreen, "width", (lib.d.getRegion(applyTo).right - lib.d.getRegion(applyTo).left) + "px");
		lib.d.setStyle(loadingScreen, "height", (lib.d.getRegion(applyTo).bottom - lib.d.getRegion(applyTo).top) + "px");
		if (applyTo.tagName.toLowerCase() == "body"){
			if ((lib.d.getRegion(applyTo).bottom - lib.d.getRegion(applyTo).top) < lib.d.getViewportHeight()){
				lib.d.setStyle(loadingScreen, "height", lib.d.getViewportHeight() + "px");
			}
		}
	}; // end position
	//
	return public;
}();
// class extension
YAHOO.photoViewer.DDOnTop = function(id, sGroup, config) {
    YAHOO.photoViewer.DDOnTop.superclass.constructor.apply(this, arguments);
};
YAHOO.extend(YAHOO.photoViewer.DDOnTop, YAHOO.util.DD, {
    startDrag: function(x, y) {
        var style = this.getEl().style;
        style.zIndex = YAHOO.photoViewer.zIndex++;
    },
    endDrag: function(x, y){
    	//var pos = "[" + lib.e.getPageX(x) + "," + lib.e.getPageY(x) + "]";
    	var pos = "[" + lib.d.getRegion(this.getEl()).left + "," + lib.d.getRegion(this.getEl()).top + "]";
		var id = this.getEl().id.split("-");
		id.splice(id.length - 1, 1);
		id = id.join("-");
		YAHOO.photoViewer.controller.getViewer(id).setProperty("xy", pos);
    }
});
// singleton objects
YAHOO.photoViewer.zIndex = 1000;
YAHOO.photoViewer.controller = function(){
	var viewers = {};
	var public = {
		init: function(){
			for (var a in YAHOO.photoViewer.config.viewers){
				viewers[a] = new YAHOO.photoViewer.base(YAHOO.photoViewer.config.viewers[a].properties.id);
				viewers[a].init();
			}
		},
		getViewer: function(id){
			return viewers[id];
		}
	};
	// private
	//
	return public;
}();
// load when dom loads
lib.e.onDOMReady(YAHOO.photoViewer.controller.init, YAHOO.photoViewer.controller, YAHOO.photoViewer.controller);