/* vim:ts=4:sts=4:sw=2:noai:noexpandtab
 *
 * JavaScript Magnification of images.
 * Copyright (c) 2005 Steven McCoy <fnjordy@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* current defects:
 * location of text, hard coded to 55 pixels above image
 * sizes hardcoded to 35 small, 70 large
 * constant speed of growing and shrinking
 * no fancy/stupid end of bar movement
 */ 

function Magnify(base_name) {
	this.base_name = base_name;

/* find images to add magic too */
	this.images = document.getElementsByName(this.base_name);

/* calculate text y position */
	this.top = this.total_offset(this.images[0],'offsetTop') - 20;

	var re = /s_/;
	for (i = 0; i < this.images.length; i++) {
		this.images[i].Magnify = this;
		this.images[i].index = i;

/* add mouse event listeners */
		this.images[i].onmouseover = this.onmouseover;
		this.images[i].onmouseout = this.onmouseout;

/* cache full size image */
		this.images[i].max_src = this.images[i].src.replace(re, "");
		this.images[i].max_image = new Image();
		this.images[i].max_image.src = this.images[i].max_src;
		this.images[i].max_width = 70;

/* keep original details */
		this.images[i].original_width = 35;
		this.images[i].original_src = this.images[i].src;

/* create text popup */
		this.images[i].div = document.createElement('DIV');
		this.images[i].div.innerHTML = this.images[i].alt;
		this.images[i].div.className = 'magnify';
		this.images[i].div.style.visibility = 'hidden';
		this.images[i].div.style.position = 'absolute';
		this.images[i].div.style.zIndex = 1;
		this.images[i].div.style.top = this.top + "px";
		document.body.appendChild(this.images[i].div);
		this.images[i].div.style.left = this.total_offset(this.images[i], 'offsetLeft') + Math.floor((this.images[i].width - this.images[i].div.offsetWidth) / 2) + "px";
	}

/* keep half size for determining center */
	this.half = Math.floor(this.images.length / 2);

/* step for changing image size */
	this.step = 5; /*was 5*/
	this.delay = 20;

/* the currently selected image */
	this.selected = null;

/* a selected entry that can fade */
	this.last_selected = null;

/* add to thunk table */
	this.id = _magnifies.length;
	_magnifies[this.id] = this;
}

Magnify.prototype.total_offset = function(element, property) {
	var total = 0;
        while (element) {
		total += element[property];
                element = element.offsetParent;
        }
	return total;
}

var _magnifies = Array();

/* animation timer */
function _magnify(id) {
	var magnify = _magnifies[id];
	var more = false;

	for (i = 0; i < magnify.images.length; i++) {
/* grow selected image */
		if (i == magnify.selected) {
			if ((magnify.images[i].width + magnify.step) > magnify.images[i].max_width) {
				magnify.images[i].width = magnify.images[i].max_width;
				magnify.images[i].height = magnify.images[i].max_width;
			} else {
				magnify.images[i].width += magnify.step;
				magnify.images[i].height += magnify.step;
				more = true;
			}
			magnify.images[i].src = magnify.images[i].max_src;

/* update title text */
			magnify.images[i].div.style.left = magnify.total_offset(magnify.images[i], 'offsetLeft') + Math.floor((magnify.images[i].width - magnify.images[i].div.offsetWidth) / 2) + "px";
			var y = Math.floor(255-255*(magnify.images[i].width-magnify.images[i].original_width)/magnify.images[i].original_width);
			/*magnify.images[i].div.style.color = "rgb("+y+","+y+","+y+")";*/
			/*magnify.images[i].div.style.color = "rgb(144,93,43)";*/
                        magnify.images[i].div.style.color = "rgb(255,255,255)";
			magnify.images[i].div.style.visibility = 'visible';

		} else {
/* calculate any additional size for being near the selected image */
			var lp = magnify.selected == null ? 0 : Math.floor((magnify.images[magnify.selected].width - magnify.images[magnify.selected].original_width) / Math.pow(2,Math.abs(i - magnify.selected)));
			var hp = magnify.selected == null ? 0 : Math.floor((70 - magnify.images[magnify.selected].original_width) / Math.pow(2,Math.abs(i - magnify.selected)));

/* remove title if not fading */
			if (magnify.selected != null) {
				magnify.images[i].div.style.visibility = 'hidden';
			}

/* shrink large images */
			if (magnify.images[i].width > (magnify.images[i].original_width+hp)) {
				if ((magnify.images[i].width - magnify.step) <= (magnify.images[i].original_width+hp)) {
					magnify.images[i].div.style.visibility = 'hidden';
					magnify.images[i].width = magnify.images[i].original_width+hp;
					magnify.images[i].height = magnify.images[i].original_width+hp;
					if (magnify.images[i].width == magnify.images[i].original_width) 
						magnify.images[i].src = magnify.images[i].original_src;
				} else {
					magnify.images[i].width -= magnify.step;
					magnify.images[i].height -= magnify.step;
					more = true;
/* update title text */
					if (magnify.selected == null && i == magnify.last_selected) {
						var y = Math.floor(255-255*(magnify.images[i].width-magnify.images[i].original_width)/magnify.images[i].original_width);
						magnify.images[i].div.style.color = "rgb("+y+","+y+","+y+")";
						magnify.images[i].div.style.visibility = 'visible';
					}
				}

/* grow neighbours to selected image */
			} else if (magnify.images[i].width < (magnify.images[i].original_width+lp)) {
				magnify.images[i].src = magnify.images[i].max_src;
				if ((magnify.images[i].width + magnify.step) >= (magnify.images[i].original_width+lp)) {
					magnify.images[i].width = magnify.images[i].original_width+lp;
					magnify.images[i].height = magnify.images[i].original_width+lp;
				} else {
					magnify.images[i].width += magnify.step;
					magnify.images[i].height += magnify.step;
					more = true;
				}
			}
		}
	}

	if (more)
		setTimeout("_magnify("+id+")", magnify.delay);
}

/* image.onmouseover */
Magnify.prototype.onmouseover = function() {
	this.Magnify.selected = this.index;
	setTimeout("_magnify("+this.Magnify.id+")", this.Magnify.delay);
}

/* image.onmouseout */
Magnify.prototype.onmouseout = function() {
	this.Magnify.last_selected = this.Magnify.selected;
	this.Magnify.selected = null;
	setTimeout("_magnify("+this.Magnify.id+")", this.Magnify.delay);
}


