function ImageRect(x, y, dx, dy)
{
	//instance variables
	this.x = 0;
	this.y = 0;
	this.dx = 0;
	this.dy = 0;
	this.x2 = 0;
	this.y2 = 0;

	//instance method
	this.set = function(x, y, dx, dy)
	{
		if(!dx){
			dx = 0;
		}
		if(!dy){
			dy = 0;
		}
		this.x = x;
		this.y = y;
		this.dx = dx;
		this.dy = dy;
		this.x2 = x + dx;
		this.y2 = y + dy;
	}

	this.setPoint = function(x, y, x2, y2)
	{
		this.Set(x, y, x2-x, y2-y);
	}

	//static method
	/* none */


	//initialize
	this.set(x, y, dx, dy);
}

var PopupImageUtil = {
	xhtml: false,

	getDocumentElement: function()
	{
		var b = null;

		if(this.xhtml && (!PopupImageAgent.isOpera() && !PopupImageAgent.isSafari())){
			b = document.documentElement;
		}
		else{
			b = document.body;
		}

		return b;
	},

	setXHtmlMode: function(onoff)
	{
		this.xhtml = !!onoff;
	},

	px2i: function(s)
	{
		return s != "" ? 1 * eval(s.split('p',1)[0]) : 0;
	},

	i2px: function(i)
	{
		return i + "px";
	}
};

var PopupImageAgent = {
    done: false,
    safari: false,
    opera: false,

    check: function()
    {
        if(!this.done){
            var ua = navigator.userAgent;
            if(window.opera){
                this.opera = true;
            }
            else if(ua.indexOf("Safari") >= 0){
                this.safari = true;
            }

            this.done = true;
        }
    },

    isOpera: function()
    {
        if(!this.done){
            this.check();
        }
        return this.opera;
    },

    isSafari: function()
    {
        if(!this.done){
            this.check();
        }
        return this.safari;
    }
}

var PopupImageController = {
	id: 0,
	zIndex: 10000,
	images: [],
	timerID: [],
	multiple: false,

	createID: function()
	{
		return ++this.id;
	},

	createZIndex: function()
	{
		return ++this.zIndex;
	},

	setMultiple: function(onoff)
	{
		this.multiple = !!onoff;
	},

	addImage: function(popupImage)
	{
		if(!this.multiple){
			var images = this.images;
			for(var i in images){
				var img = images[i];
				if(img){
					if(img.status >= __POPUP_STATUS_READY__ && img.status <= __POPUP_STATUS_SETSTYLE__){
						this.removeStart(images[i]);
					}
				}
			}
		}
		this.images[popupImage.id] = popupImage;
	},

	setTimeout: function(popupImage)
	{
		var imageID = popupImage.id;
		if(this.images[imageID]){
			this.timerID[imageID] = setTimeout("PopupImageController.images["+imageID+"].run()", popupImage.popupMsec);
		}
	},

	clearTimeout: function(popupImage)
	{
		var imageID = popupImage.id;
		if(this.timerID[imageID]){
			clearTimeout(this.timerID[imageID]);
			this.timerID[imageID] = null;
		}
	},

	removeImage: function(popupImage)
	{
		if(popupImage && popupImage.img){
			if(popupImage.imageValid){
				document.body.removeChild(popupImage.img);
			}
			popupImage.img = null;

			var imageID = popupImage.id;
			PopupImageController.images[imageID] = null;

			this.gc();
		}
	},

	gc: function()
	{
		var images = this.images;
		var newImages = new Array();

		var idList = this.timerID;
		var newTimerID = new Array();

		for(var i in images){
			if(images[i]){
				newImages[i] = images[i];
			}
		}
		this.images = newImages;

		for(var i in idList){
			if(idList[i]){
				newTimerID[i] = idList[i];
			}
		}
		this.timerID = newTimerID;
	},

	removeStart: function(popupImage)
	{
		if(popupImage && popupImage.img){
			if(!popupImage.removed){
				popupImage.removed = true;

				this.clearTimeout(popupImage);
				if(popupImage.quickRemove){
					PopupImageController.removeImage(popupImage);
				}
				else if(popupImage.status != __POPUP_STATUS_ZOOM_OUT__){
					popupImage.unsetImageStyle(popupImage.img);
					popupImage.status = __POPUP_STATUS_ZOOM_OUT__;
					popupImage.run();
				}
			}
		}
	},

	onRemove: function()
	{
		PopupImageController.removeStart(this.popupImage);
		return true;
	}
};

var __POPUP_STATUS_READY__ = 1;
var __POPUP_STATUS_IMAGE_LOADING__ = 2;
var __POPUP_STATUS_ZOOM_IN__ = 3;
var __POPUP_STATUS_SETSTYLE__ = 4;
var __POPUP_STATUS_ZOOM_OUT__ = 5;
var __POPUP_STATUS_REMOVE__ = 8;
var __POPUP_STATUS_END__ = 99;
var __POPUP_MAXSTEP__ = 8;
var __POPUPMSEC__ = 30;

function PopupImage()
{
	//instance variables
	this.id = PopupImageController.createID();
	this.status = __POPUP_STATUS_READY__;
	this.url = "";
	this.img = null;
	this.startRect = new ImageRect();
	this.targetRect = null;
	this.screen = new ImageRect();
	this.realImgWidth = 0;
	this.realImgHeight = 0;
	this.stepCount = 0;
	this.maxStep = __POPUP_MAXSTEP__;
	this.popupMsec = __POPUPMSEC__;
	this.imageValid = false;
	this.quickRemove = false;
	this.stylePreload = true;
	this.marginLeft = 0;
	this.marginRight = 0;
	this.marginTop = 0;
	this.marginBottom = 0;
	this.removed = false;

	//instance method
	this.setURL = function(url)
	{
		this.url = url;
	}

	this.setStartPos = function(x, y)
	{
		this.startRect.set(x, y);
	}

	this.setStep = function(num)
	{
		if(num > 0){
			this.maxStep = num;
		}
	}

	this.setTimerMSec = function(msec)
	{
		if(msec > 0){
			this.popupMsec = msec;
		}
	}

	this.setQuickRemove = function(onoff)
	{
		this.quickRemove = !!onoff;
	}

	this.setStylePreload = function(onoff)
	{
		this.stylePreload = !!onoff;
	}

	this.setMarginLeft = function(pixel)
	{
		this.marginLeft = pixel;
	}

	this.setMarginRight = function(pixel)
	{
		this.marginRight = pixel;
	}

	this.setMarginTop = function(pixel)
	{
		this.marginTop = pixel;
	}

	this.setMarginBottom = function(pixel)
	{
		this.marginBottom = pixel;
	}

	this.start = function()
	{
		PopupImageController.addImage(this);

		if(!this.img){
		    if(PopupImageAgent.isSafari()){
                this.img = new Image();
		    }
		    else{
    			this.img = document.createElement("IMG");
		    }

		    this.img.src = this.url;
		}

		this.status = __POPUP_STATUS_IMAGE_LOADING__;
		this.run();
	}

	this.stop = function()
	{
		this.status = __POPUP_STATUS_READY__;
		PopupImageController.clearTimeout(this);
		PopupImageController.images[this.id] = null;
	}

	this.run = function()
	{
		var img = this.img;
		var screen = this.screen;

		switch(this.status){
		case __POPUP_STATUS_IMAGE_LOADING__ :
			if(img && img.complete){

			    if(PopupImageAgent.isSafari()){
    			    var width = img.width;
    			    var height = img.height;
    			    var url = img.src;
    			    this.img = document.createElement("IMG");
        			this.img.src = url;
        			this.img.width = width;
        			this.img.height = height;
        			img = this.img;
			    }

    			this.img.style.zIndex = PopupImageController.createZIndex();
			    this.img.style.position = "absolute";
			    this.img.popupImage = this;

				var b = PopupImageUtil.getDocumentElement();

			    if(PopupImageAgent.isSafari()){
				    screen.set(b.scrollLeft, b.scrollTop, window.innerWidth, window.innerHeight);
			    }
				else{
				    screen.set(b.scrollLeft, b.scrollTop, b.clientWidth, b.clientHeight);
			    }

				if(this.stylePreload){
					this.setImageStyle(img);
					img.style.borderColor = "transparent";
				}

				this.realImgWidth = img.width;
				this.realImgHeight = img.height;

				this.targetRect = new ImageRect();
				var targetX = Math.round(screen.x + (screen.dx - this.realImgWidth) / 2) + this.marginLeft - this.marginRight;
				if(targetX < this.marginLeft){
					targetX = this.marginLeft;
				}

				var targetY = Math.round(screen.y + (screen.dy - this.realImgHeight) / 2) + this.marginTop - this.marginBottom;
				if(targetY < this.marginTop){
					targetY = this.marginTop;
				}

				this.targetRect.set(targetX, targetY, this.realImgWidth, this.realImgWidth);

				img.style.width = PopupImageUtil.i2px(0);
				img.style.height = PopupImageUtil.i2px(0);
				img.style.left = PopupImageUtil.i2px( this.startRect.x );
				img.style.top = PopupImageUtil.i2px( this.startRect.y );

				this.stepCount = 0;

				document.body.insertBefore(img, null);
				this.imageValid = true;

				this.status = __POPUP_STATUS_ZOOM_IN__;
			}
			break;

		case __POPUP_STATUS_ZOOM_IN__ :
		case __POPUP_STATUS_ZOOM_OUT__ :
			var ratio = this.onZoom(this.stepCount, this.maxStep) / this.maxStep;

			var imgWidth = this.realImgWidth * ratio;
			var imgHeight = this.realImgHeight * ratio;
			var startX = this.startRect.x;
			var startY = this.startRect.y;
			var targetX = this.targetRect.x;
			var targetY = this.targetRect.y;

			var newImgLeft = 0;
			if(startX > targetX){
				newImgLeft = startX - Math.abs(startX - targetX) * ratio;
			}
			else{
				newImgLeft = startX + Math.abs(startX - targetX) * ratio;
			}
			if(newImgLeft < this.marginLeft){
				newImgLeft = this.marginLeft;
			}

			var newImgTop = 0;
			if(startY > targetY){
				newImgTop = startY - Math.abs(startY - targetY) * ratio;
			}
			else{
				newImgTop = startY + Math.abs(startY - targetY) * ratio;
			}
			if(newImgTop < this.marginTop){
				newImgTop = this.marginTop;
			}

			var img_style = img.style;
			img_style.width = PopupImageUtil.i2px(imgWidth);
			img_style.height = PopupImageUtil.i2px(imgHeight);
			img_style.left = PopupImageUtil.i2px(newImgLeft);
			img_style.top = PopupImageUtil.i2px(newImgTop);

			if(this.status == __POPUP_STATUS_ZOOM_IN__){
				if(++this.stepCount > this.maxStep){
					this.stepCount = this.maxStep;
					this.status = __POPUP_STATUS_SETSTYLE__;
				}
			}
			else if(this.status == __POPUP_STATUS_ZOOM_OUT__){
				if(--this.stepCount <= 0){
					this.stepCount = 0;
					this.status = __POPUP_STATUS_REMOVE__;
				}
			}
			break;

		case __POPUP_STATUS_SETSTYLE__ :
			this.setImageStyle(img);
			this.status = __POPUP_STATUS_END__;
			break;

		case __POPUP_STATUS_REMOVE__ :
			PopupImageController.removeImage(this);
			this.status = __POPUP_STATUS_READY__;
			break;

		case __POPUP_STATUS_END__ :
			img.onclick = PopupImageController.onRemove;
			this.status = __POPUP_STATUS_READY__;
			return;

		default :
			return;
		}

		PopupImageController.setTimeout(this);
	}


	//static method
	this.setImageStyle = function(img){}

	this.unsetImageStyle = function(img)
	{
	    if(img && img.style){
    		with(img.style){
    			border = "none";
    		}
	    }
	}

	this.onZoom = function(stepCount, maxStep)
	{
		return stepCount;
	}

	this.onZoom2 = function(stepCount, maxStep)
	{
		return stepCount * stepCount / maxStep;
	}
}



function popImg(evt, url)
{
	var x = 0;
	var y = 0;

	PopupImageUtil.setXHtmlMode(true);
//	PopupImageController.setMultiple(true);

	if(document.all){
		var b = PopupImageUtil.getDocumentElement();
		x = event.clientX + b.scrollLeft;
		y = event.clientY + b.scrollTop;
	}
	else if(evt){
		x = evt.pageX;
		y = evt.pageY;
	}

	var popImage = new PopupImage();
	popImage.setURL(url);
	popImage.setStartPos(x, y);
//	popImage.onZoom = popImage.onZoom2;
//	popImage.setStep(20);
//	popImage.setTimerMSec(10);
//	popImage.setQuickRemove(true);
//	popImage.setMarginLeft(20);
//	popImage.setMarginRight(100);
//	popImage.setMarginTop(100);
//	popImage.setMarginBottom(100);
//	popImage.setStylePreload(false);

	popImage.setImageStyle = function(img)
	{
	    if(img && img.style){
		  with(img.style){
    			backgroundColor = "#fff";
    			borderStyle = "solid";
    			borderWidth = "1px 1px 1px 1px";
    			borderColor = "#333 #333 #333 #333";
    			padding = "3px";
    			if(!!cursor){
    			    cursor = "hand";
    			}
    		}
	    }
	}

	popImage.start();
}

/*

<a href="../../js/imagesName.gif" onclick="popImg(event,'imagesName.jpg');return false;" >ƒ{ƒ^ƒ“</a>

*/
