
//Bugs:
//Need IE specific style sheet code.
//Would like to detect which opacity is supported... object detection?


var firstTime = true;
var req = null;
var newImage;
var isFading = false;
var textFading = false;
var step = 10;//5
var interval = 30;//30
var preloaded;
var sheet;
var whichPhoto;

// 1. Set opacity of photo to zero prior to fade in
sheet = document.styleSheets[0];
sheet.cssRules[5].style.visibility = "hidden";
sheet.cssRules[7].style.opacity = 0;

var model={
	pageTitle : "",
	postTitle : "",
	postSeries : "",
	postCaption : "",
	postEntry : "",
	imageSrc : "",
	imageAlt : "",
	imageTitle : "",
	imageHeight : "",
	imageWidth : "",
	currentsrc : "",
	// settings...
	init : function() {
		this.linkaddress = window.location;
		this.height = view.photo1.div.style.height;
		this.fullwidth = view.photo1.div.style.width;
		this.imageSrc = view.photo1.div.src;
		calculateHalfWidth(view.photo1.div);
		this.prevhref = document.getElementsByTagName("area")[0].getAttribute("href");
		this.nexthref = document.getElementsByTagName("area")[1].getAttribute("href");
		if (view.titletag.childNodes[0])
		{
			this.postTitle = view.titletag.childNodes[0].nodeValue;
		}
		else
		{
			this.postTitle = null;
		}
		try {
			this.postSeries = view.seriestag.childNodes[0].nodeValue;
		} catch(e) {
			this.postSeries = null;
		}
	},
	getNewValues : function(XMLdoc) {
		{
			//parse new values from external document
			//null value issue in Safari
			var imagetag = XMLdoc.getElementsByTagName("img")[0];
			model.imageSrc = imagetag.src;
			this.imageAlt = imagetag.alt;
			this.imageTitle = imagetag.title;
			// title, series, caption, and entry may not exist
			this.pageTitle = XMLdoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
			try {
				this.postTitle = XMLdoc.getElementsByTagName("h2")[0].childNodes[0].nodeValue;
			} catch(e) {
				this.postTitle = null;
			}
			this.postDate = XMLdoc.getElementsByTagName("p")[0].childNodes[0].nodeValue;
			try {
				this.postSeries = XMLdoc.getElementsByTagName("h3")[0].childNodes[0].nodeValue;
			} catch(e) {
				this.postSeries = null;
			}
			try {
				this.postCaption = XMLdoc.getElementsByTagName("p")[1].childNodes[0].nodeValue;
			} catch(e) {
				this.postCaption = null;
			}
			if (XMLdoc.getElementsByTagName("div")[1].id == "entry")
			{
				if (document.importNode)
				{
					try {
						this.postEntry = document.importNode(XMLdoc.getElementsByTagName("div")[1], true);
						this.postEntry.setAttribute("id","temp");
					} catch(e) {
						this.postEntry = null;
					}
				}
				else
				{
					try {
						this.postEntry = XMLdoc.getElementsByTagName("div")[1].cloneNode(true);
						this.postEntry.setAttribute("id","temp");
					} catch(e) {
						this.postEntry = null;
					}
				}
			}
			else
			{
				this.postEntry = null; //entry is empty and "image" becomes div[1] in Safari
			}

			calculateHalfWidth(imagetag);
			this.prevhref = XMLdoc.getElementsByTagName("area")[0].getAttribute("href");
			this.nexthref = XMLdoc.getElementsByTagName("area")[1].getAttribute("href");
		}
	}
}

var view={
	init : function() {
		this.photo1 = document.getElementById("photo1");
		this.imagediv = document.getElementById("image");
		this.postDate = document.getElementById("entrydate");
		this.entrydiv = document.getElementById("entry");
		this.titletag = document.getElementById("title");
		this.seriestag = document.getElementById("series");
		this.captiontag = document.getElementById("caption");
		this.prevlink2 = document.getElementById("previous");
		this.nextlink2 = document.getElementById("next");
		var myMap = document.getElementById("navmap");
		if (myMap) {
			var myAreas = myMap.getElementsByTagName("area");
			this.prevarea = myAreas[0];
			this.nextarea = myAreas[1];
		}
		this.createPhoto2();
		this.createLinks();
		},
	createTitle : function() {
		if (model.postTitle)
		{
			view.titletag.childNodes[0].nodeValue = model.postSeries + ": " + model.postTitle;
			view.seriestag.childNodes[0].nodeValue = "";
		}
		else
		{
			view.titletag.appendChild(document.createTextNode(model.postSeries));
			view.seriestag.childNodes[0].nodeValue = "";
		}
	},
	createPhoto2 : function() {
		if (document.createElement) {
			this.photo2 = document.createElement("img");
			this.photo2.setAttribute("id","photo2");
			//sheet.cssRules[6].style.visibility = "hidden";
			this.photo2.style.visibility = "hidden";
			this.imagediv.appendChild(this.photo2);
			//try inserting it before photo1... didn't work
			//this.imagediv.insertBefore(this.photo2,this.photo1);
		}
	},
	createLinks : function() {
		this.prevText = document.createElement("div");
		setOpacity(this.prevText,0);
		this.prevText.setAttribute("id","prevText");
		this.prevText.appendChild(document.createTextNode("« previous"));
		this.imagediv.appendChild(this.prevText);
		this.nextText = document.createElement("div");
		setOpacity(this.nextText,0);
		this.nextText.setAttribute("id","nextText");
		this.nextText.appendChild(document.createTextNode("next »"));
		this.imagediv.appendChild(this.nextText);
		this.prevlink = document.createElement("a");
		this.prevlink.setAttribute("id","prevlink");		
		this.nextlink = document.createElement("a");
		this.nextlink.setAttribute("id","nextlink");
		this.imagediv.appendChild(this.prevlink);
		this.imagediv.appendChild(this.nextlink);
		this.prevText = new linkDiv("prevText");
		this.nextText = new linkDiv("nextText");
		this.photo1 = new linkDiv("photo1");
	},
	removePhoto2 : function(){
		//view.purge(this.photo1);
		this.imagediv.removeChild(this.photo2);
	},
	manageLinks : function() {
		this.imagediv.style.height = model.height;
		this.imagediv.style.width = model.fullwidth;
		setOpacity(this.prevText.div,0);
		setOpacity(this.nextText.div,0);
		
		if (model.prevhref != "#")
		{
				this.prevText.div.childNodes[0].nodeValue ="« previous";
				this.setLinkSize();
				this.prevarea.setAttribute("href", model.prevhref);
				this.prevlink.setAttribute("href", model.prevhref);
				if (this.prevlink2.childNodes[0].nodeName == "A")
				{
					this.prevlink2.childNodes[0].setAttribute("href", model.prevhref);
				}
				else
				{
					//remove plain text "previous"
					this.prevlink2.removeChild(this.prevlink2.childNodes[0]);
					//create new anchor
					var anchor = document.createElement("a");
					anchor.setAttribute("href", model.prevhref);
					anchor.appendChild(document.createTextNode("« previous"));
					this.prevlink2.appendChild(anchor);
				}
				view.setLinkHandlers();
		}
		else
		{
			this.prevlink.setAttribute("href", "#");
			this.manageLinkText();
		}
		
		
		if (model.nexthref != "#")
		{
				this.nextText.div.childNodes[0].nodeValue ="next »";
				this.setLinkSize();
				this.nextarea.setAttribute("href", model.nexthref);
				this.nextlink.setAttribute("href", model.nexthref);
				if (this.nextlink2.childNodes[0].nodeName == "A")
				{
					this.nextlink2.childNodes[0].setAttribute("href", model.nexthref);
				}
				else
				{
					//remove plain text "next"
					this.nextlink2.removeChild(this.nextlink2.childNodes[0]);
					//create new anchor
					var anchor = document.createElement("a");
					anchor.setAttribute("href", model.nexthref);
					anchor.appendChild(document.createTextNode("next »"));
					this.nextlink2.appendChild(anchor);
				}
				view.setLinkHandlers();
		}
		else
		{
			this.nextlink.setAttribute("href", "#");
			this.manageLinkText();
		}
	},
	manageLinkText : function() {
		if (!textFading)
		{
			if (model.prevhref == "#")
			{
				this.prevText.div.childNodes[0].nodeValue = "this is the oldest";
			}
			if (model.nexthref == "#")
			{
				this.nextText.div.childNodes[0].nodeValue = "this is the newest";
			}
		}
		else
		{
			window.setTimeout("view.manageLinkText()",1000);
		}
	},
	setLinkHandlers : function() {
		document.onmouseover = showNav;
		document.onmouseout = hideNav;
		this.prevlink.onclick = controller.switchImage;
		this.nextlink.onclick = controller.switchImage;
		
	},
	setLinkSize : function() {
		this.prevlink.style.height = model.height;
		this.prevlink.style.width = model.width;
		this.nextlink.style.height = model.height;
		this.nextlink.style.width = model.width;
	},
	// purge takes DOM reference and deletes functions http://javascript.crockford.com/memory/leak.html
	// then use removeChild to remove DOM nodes
	purge : function(d) {
		var a = d.attributes, i, l, n;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i += 1) {
				n = a[i].name;
				if (typeof d[n] === 'function') {
					d[n] = null;
				}
			}
		}
		a = d.childNodes;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i += 1) {
				this.purge(d.childNodes[i]);
			}
		}
	}
}

var controller={
	init : function() {
		view.init();
		model.init();
		view.createTitle();
		view.manageLinks();
		whichPhoto = view.photo1.div;
		preloadImage();
		},
	switchImage : function(e) //onclick
		{
		if (isFading)
		{
			return false;
		}
		hideNavs();
		textFading = true;
		isFading == true;
		if (this.id == "prevlink")
		{
			model.linkaddress = model.prevhref;//document.getElementsByTagName("area")[0].getAttribute("href");
			if (model.linkaddress != "#")
			{
				loader.loadXMLDoc(model.linkaddress);
			}
			else
			{
				showNav(e);
			}
		}
		if (this.id == "nextlink")
		{
			model.linkaddress = model.nexthref;//document.getElementsByTagName("area")[1].getAttribute("href");
			if (model.linkaddress != "#")
			{
				loader.loadXMLDoc(model.linkaddress);
			}
			else
			{
				showNav(e);
			}
		}
			return false;//prevents the link from being followed
		},
	loadImage : function() {
		//set fields here
		//DOM method doesn't work in Firefox:
		//if both series and title, splice together
		if (model.pageTitle)
		{
			document.title = model.pageTitle;
		}
		else
		{
			document.title = "Tony Green / Photography";
		}

		if (model.postTitle)
		{
			view.titletag.childNodes[0].nodeValue = model.postSeries + ": " + model.postTitle;
			view.seriestag.childNodes[0].nodeValue = "";
		}
		else
		{
			view.titletag.childNodes[0].nodeValue = model.postSeries;
			view.seriestag.childNodes[0].nodeValue = "";
		}
		if (model.postDate)
		{
			view.postDate.childNodes[0].nodeValue = model.postDate;
		}
		if (model.postCaption)
		{
			try {
				view.captiontag.childNodes[0].nodeValue = model.postCaption;
			} catch(e) {
				view.captiontag.appendChild(document.createTextNode(model.postCaption));
			}
		}
		else
		{
			try {
				view.captiontag.childNodes[0].nodeValue = "";
			} catch(e) {
				view.captiontag.appendChild(document.createTextNode(""));
			}
		}
		// If postEntry was not set (Safari), it's empty anyway.
		try {
			if (model.postEntry) {
				view.entrydiv.parentNode.insertBefore(model.postEntry, view.entrydiv);
				view.entrydiv.parentNode.removeChild(view.entrydiv);
				document.getElementById("temp").setAttribute("id","entry");
				view.entrydiv = document.getElementById("entry");
			}
			else
			{
				try {
					//childNodes[1] instead of [0] skips over white space node to get to <P>
					view.entrydiv.childNodes[1].firstChild.nodeValue = "";
				} catch(e) {
					//alert("Error setting entry to empty string: " + e);
				}
			}
		} catch(e) {
			alert("error inserting entry");
		}
		
		//This doesn't work in Safari either
		//view.entrydiv.innerHTML = model.postEntry.innerHTML;
		whichPhoto = view.photo2;
		preloadImage();
	}
}

var loader={
	loadXMLDoc : function(url) {
		// branch for native XMLHttpRequest object
		req = null;
/*		try {
			if (window.netscape && window.netscape.security.PrivilegeManager.enablePrivilege)
			{
				netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
			}
		} catch (e) {
				alert(e);
		}*/
		if (window.XMLHttpRequest && !(window.ActiveXObject)) {
			try {
				req = new XMLHttpRequest();
			} catch(e) {
				alert("New request failed: " + e);
				req = false;
			}
		// branch for IE/Windows ActiveX version
		} else if(window.ActiveXObject) {
			try {
				req = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				try {
					req = new ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {
					req = false;
				}
			}
		}
		if(req) {
			//alert("req exists");
/*			if (window.netscape && window.netscape.security.PrivilegeManager.enablePrivilege)
			{
				netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
			}*/
			req.onreadystatechange = function () {};
			req.onreadystatechange = this.processReqChange;
			try {
				req.open("GET", url, true);//We are getting here in Firefox
				req.overrideMimeType("text/xml"); //works in Safari at least
			} catch (e) {
				alert("Open failed: " + e);
			}
			try {
			
				req.send(null);
			} catch (e) {
				alert("Send error: " + e);
			}
		}
	},

	processReqChange : function() {
/*		if (window.netscape &&
			window.netscape.security.PrivilegeManager.enablePrivilege)
			{
				netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
			}*/
		// only if req shows "loaded"
		if (req.readyState == 4) {
			// only if "OK"
			if (req.status == 200) {
				try {
					model.getNewValues(req.responseXML.documentElement);
					controller.loadImage();
				} catch (e) {
				alert("Call to getNewValues failed: " + e);
				}
			} else {
				alert("There was a problem retrieving the XML data:\n" +
					req.statusText);
			}
		} else {
			;
		}
	}
}

function loadError() {
	alert(model.imageSrc + " failed to load");
}

function preloadImage() {
	try {
		preloaded = false;
		newImage = new Image();
		// event needs to be assigned before src
		// that would explain why setupPhoto is never called sometimes
		// Still not sure best way to call setupPhoto when onload doesn't fire (image in cache, etc)
		newImage.onload = setupPhoto;
		newImage.onerror = loadError;
		newImage.src = model.imageSrc;
	} catch(e) {
		alert("preloadImage failed: " + e);
	}
	//window.setTimeout("checkPreload()",300);//not sure what a good value would be???
	//onload is never fires for images that are in cache???
	//set a watchdog variable and unset it in setCat. Call a function in the future to see if it's NOT unset, 
	//and if not, call setCat.
}

function checkPreload() {
	if (!preloaded)
	{
		setupPhoto(); //Call setupPhoto2 manually in case image.onload never fires.
	}
}

function setupPhoto() {
	preloaded = true;
	try
	{
	whichPhoto.src = newImage.src; // this causes a flash under load
	} catch(e) {
//		window.setTimeout("preloadImage()",500);
		alert("src empty " + model.imageSrc + e);
	}
	try {
	//view.purge(newImage);
	//newImage = null;
	whichPhoto.style.width = model.fullwidth;//move to view or controller?
	whichPhoto.alt = model.imageAlt;
	whichPhoto.title = model.imageTitle;
	whichPhoto.style.height = model.height;//move to view or controller?
	} catch(e) {
//		window.setTimeout("preloadImage()",500);
		alert("other problem " + model.imageSrc + e);
	}
	textFading = true;//works here for some reason
	view.manageLinks();
	setOpacity(whichPhoto,0);
	whichPhoto.style.visibility = "visible";
	if (firstTime)
	{
		window.setTimeout(function() {fadeIn(view.photo1.div,0,100);},0);
		firstTime = false;
	}
	else
	{
		crossfade();//this has to move
	}
}

function crossfade() {

	isFading = true;
	setOpacity(view.photo2,0);
	view.photo2.style.visibility = "visible";
	view.photo2.style.display = "inline";
	if (view.photo1.div.style.opacity == .7)
	{
		window.setTimeout(function() {fadeOut(view.photo1.div,70,0);},10);
	}
	else
	{
		window.setTimeout(function() {fadeOut(view.photo1.div,100,0);},10);
	}
	window.setTimeout(function() {fadeIn(view.photo2,0,100);},15);
	window.setTimeout("switchSrc()",2000);

}

function switchSrc () {
// copy attributes from photo2 to photo1 (on top)
	view.photo1.div.src = view.photo2.src;
	view.photo1.div.alt = view.photo2.alt;
	view.photo1.div.title = view.photo2.title;
	view.photo1.div.style.height = model.height;//view.photo2.style.height;
	view.photo1.div.style.width = model.fullwidth;//view.photo2.style.width;
	view.photo2.removeAttribute("src");
	view.photo2.removeAttribute("alt");
	view.photo2.removeAttribute("title");
	view.photo2.removeAttribute("style");
	setOpacity(view.photo1.div,100);
	setOpacity(view.photo2,0);
	view.photo2.style.visibility = "hidden";
//	window.setTimeout(alert("photo1 " + view.photo1.div.style.visibility + " photo2 " + view.photo2.style.visibility),1000);
	isFading = false;
}

function showNav(e) {
	if (!e) var e = window.event;
	var tg = (window.event) ? e.srcElement : e.target;
	if (tg.id == "prevlink")
	{
		view.prevText.direction = "in";
		view.prevText.max = 100;
		view.prevText.fader();
		view.photo1.direction = "out";
		view.photo1.min = 70;
		view.photo1.fader();
	}
	if (tg.id == "nextlink")
	{
		view.nextText.direction = "in";
		view.nextText.max = 100;
		view.nextText.fader();
		view.photo1.direction = "out";
		view.photo1.min = 70;
		view.photo1.fader();
	}
}

function hideNavs()
{	//hide nav text, but leave photo alone.
	view.prevText.direction = "out";
	view.prevText.min = 0;
	view.prevText.fader();
	view.nextText.direction = "out";
	view.nextText.min = 0;
	view.nextText.fader();
}

function hideNav(e)
{
	//this fires on click as well
	if (!e) var e = window.event;
	var tg = (window.event) ? e.srcElement : e.target;
	if (tg.id == "prevlink")
	{
		view.prevText.direction = "out";
		view.prevText.min = 0;
		view.prevText.fader();
		view.photo1.direction = "in";
		view.photo1.min = 70;
		view.photo1.max = 100;
		view.photo1.fader();
	}
	if (tg.id == "nextlink")
	{
		view.nextText.direction = "out";
		view.nextText.min = 0;
		view.nextText.fader();
		view.photo1.direction = "in";
		view.photo1.min = 70;
		view.photo1.max = 100;
		view.photo1.fader();
	}
}

function setOpacity(obj, opacity) {
	opacity = (opacity == 100)?99.999:opacity;

	// IE/Win
	obj.style.filter = "alpha(opacity="+opacity+")";
	
	// Safari<1.2, Konqueror
	obj.style.KHTMLOpacity = opacity/100;
	
	// Older Mozilla and Firefox
	obj.style.MozOpacity = opacity/100;
	
	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = opacity/100;
}

function fadeIn(obj,opacity,end) {
	if (opacity <= end) {
		setOpacity(obj, opacity);
		opacity += step;
		window.setTimeout(function() {fadeIn(obj,opacity,end);}, interval);
	}
	else
	{
		textFading = false;
	}
}

function fadeOut(obj,opacity,end) {
	if (opacity >= end) {
		setOpacity(obj, opacity);
		opacity -= step;
		window.setTimeout(function() {fadeOut(obj,opacity,end);}, interval);
	}
	else
	{
		textFading = false;
	}
}

function calculateHalfWidth(imagetag) {
	model.imageHeight = parseFloat(imagetag.style.height);
	if (model.imageHeight > 100)
	{
		model.height = model.imageHeight * .1 + "em";
	}
	else
	{
		model.height = model.imageHeight + "em";
	}
	
	model.imageWidth = parseFloat(imagetag.style.width);
	if (model.imageWidth > 100)
	{
		model.width = (model.imageWidth/2) * .1 + "em";
		model.fullwidth = model.imageWidth * .1 + "em";
	}
	else
	{
		model.width = (model.imageWidth/2) + "em";
		model.fullwidth = model.imageWidth + "em";
	}
}


function linkDiv(divID) {
	//the "constructor"
	this.direction = "";
	this.min = 0;
	this.max = 100;
	this.div = document.getElementById(divID);
	this.div.style.opacity = 0;
}
//add a method
linkDiv.prototype.fader = function() {
	var self = this;
	var opacity = (self.div.style.opacity * 100);
	var fade2 = function()
	{
		if (self.direction == "in")
		{
			opacity = opacity + step;
			if (opacity % 10 > 0)
			{
			opacity = Math.round(opacity);
			}
			setOpacity(self.div,opacity);
			if (opacity < self.max)
				window.setTimeout(fade2,interval);

		}
		if (self.direction == "out")
		{
			if (opacity > self.min)
			{
			opacity = opacity - step;
			if (opacity % 10 > 0)
			{
				opacity = Math.round(opacity);
			}
			setOpacity(self.div,opacity);
			if (opacity > self.min)
				window.setTimeout(fade2,interval);
			}
		}
	}

	setTimeout(function () {fade2();},interval);
}

function pageLoader() {
	controller.init();
}
function pageUnloader() {
	//imgObj.cleanup();
}

window.onload = pageLoader;
