//############################################
// parameters
var gridNX = 5;
var gridNY = 4;
var borderWidth = 3;
var sizeVelocity = .2;
var posVelocity = .1;
var mosaicSpacing = 1;
var focusSizeFactor = 4;
var sizeMagnetFactor = .01;
var posMagnetFactor = .01;
var opacityUnfocused = 40;
var opacityFactor = 80;
var opacityVelocityInc = .1;
var opacityVelocityDec = .05;
var captionSizeFactor = .1;
var fontSize = 8;

function opacity(o, opacity) {
  o.style.opacity = (opacity / 100);
  o.style.MozOpacity = (opacity / 100);
  o.style.KhtmlOpacity = (opacity / 100);
  o.style.filter = "alpha(opacity=" + opacity + ")";
}

var show = {
	items: [],
	wdw  : {},
  destroy : false,
  link : null,

	init: function(windowElementId, imagesElementId){
		this.wdw.element = document.getElementById(windowElementId);
		//this.wdw.element.onselectstart = function() { return false; }
		//this.wdw.element.ondrag        = function() { return false; }
		var images = document.getElementById(imagesElementId).getElementsByTagName('img');
		var links = document.getElementById(imagesElementId).getElementsByTagName('a');

		var ptr = 0;
		for(var y=0; y<gridNY; y++){
			for(var x=0; x<gridNX; x++){
				var item = document.createElement('div');
				item.img = document.createElement('img');
				item.img.className = 'unfocused';
				item.img.src = images[ptr] ? images[ptr].src : '';
				item.appendChild(item.img);
				item.caption = document.createElement('span');
        item.caption.innerHTML = images[ptr] ? images[ptr].alt : '';
				item.appendChild(item.caption);
        item.link = links[ptr] ? links[ptr].href : '';
				item.src = item.img.src;
				show.wdw.element.appendChild(item);
				item.gmt = {
          op: 0, // caption opacity
					ox: 0, oy: 0, // origin coord
					tx: 0, ty: 0, // target coord
					x : 0, y : 0, // actual coord
					ratio : 1,
          ns: 0, // native size
          os: 0, // origin size
          ts: 0, // target size
          s : 0  // actual size
				};
				show.items.push(item);
				item.onmouseover = function(){
          if (show.focusedItem){
            show.focusedItem.gmt.os=show.wdw.w/gridNX/(mosaicSpacing+1);
            show.focusedItem.img.className = 'unfocused';
          }
          this.gmt.os=show.wdw.w*focusSizeFactor/gridNX/(mosaicSpacing+1);
          this.img.className = 'focused';
          show.focusedItem = this;
        };
				item.onmouseout = function(){
          if (show.focusedItem){
            show.focusedItem.gmt.os=show.wdw.w/gridNX/(mosaicSpacing+1);
            show.focusedItem.img.className = 'unfocused';
          }
          show.focusedItem=null;
        };
				item.onclick = function(){
          show.link = this.link;
          for(var i=0; o = show.items[i]; i++){
            o.gmt.ts = 0;
            o.gmt.tx = show.wdw.w/2;
            o.gmt.ty = show.wdw.h/2;
          }
          show.destroy = true;
        };
        ptr++;
			}
		}
		show.resize();
		mouse.y = show.wdw.h/2;
		mouse.x = show.wdw.w/2;
		show.run();
	},
  
  process: function(o){
    if(!show.destroy){
      var ddx=Math.pow(dx=mouse.x-o.gmt.ox,2)*.01;
      var ddy=Math.pow(dy=mouse.y-o.gmt.oy,2)*.01;
      o.gmt.ts=o.gmt.os+(ddx+ddy)*sizeMagnetFactor;
      o.gmt.tx=o.gmt.ox+ddx*(dx>0?1:-1)*posMagnetFactor;
      o.gmt.ty=o.gmt.oy+ddy*(dy>0?1:-1)*posMagnetFactor;
    }
    o.gmt.s+=(o.gmt.ts-o.gmt.s)*sizeVelocity;
    o.gmt.x+=(o.gmt.tx-o.gmt.x)*posVelocity;
    o.gmt.y+=(o.gmt.ty-o.gmt.y)*posVelocity;
    o.gmt.op+=((o==show.focusedItem)?opacityVelocityInc:-opacityVelocityDec);
    if(o.gmt.op>1) o.gmt.op=1;
    if(o.gmt.op<0) o.gmt.op=0;
    if(show.destroy) o.gmt.op=0;
	},

  draw: function(o){
    if(o.img.complete){
      if(!o.loaded){
        if(!o.tmp){
          o.tmp = new Image();
          o.tmp.src = o.src;
        }
        if(o.tmp.complete){
          if(o.tmp.width && o.tmp.height){
            o.style.visibility = 'visible';
            o.gmt.ratio=o.tmp.width/o.tmp.height;
          }
          else{
					  o.gmt.ratio=1;
          }
          o.gmt.ns=o.tmp.width;
          o.gmt.os=show.wdw.w/gridNX/(mosaicSpacing+1);
          o.gmt.s=0;
          o.gmt.x=show.wdw.w/2;
          o.gmt.y=show.wdw.h/2;
          o.loaded = true;
          o.tmp = false;
        }
      }
      // frame
      o.style.left = Math.round(o.gmt.x - o.gmt.s/2)+'px';
      o.style.top = Math.round(o.gmt.y - o.gmt.s/o.gmt.ratio/2)+'px';
      o.style.width  = Math.round(o.gmt.s)+'px';
      o.style.height = Math.round(o.gmt.s/o.gmt.ratio)+'px';
      o.style.zIndex = Math.floor(o.gmt.s);
      if(o==show.focusedItem) opacity(o.img,100);
      else opacity(o.img,Math.min((o.gmt.s*gridNX*(mosaicSpacing+1)/show.wdw.w-1)*opacityFactor+opacityUnfocused,100));
      // image
      o.img.style.borderWidth = Math.round(o.gmt.s*borderWidth/100)+'px';
      // caption
      o.caption.style.top = Math.round(o.gmt.s/o.gmt.ratio+o.gmt.s*borderWidth/100)-1+'px';
      o.caption.style.width  = Math.round(o.gmt.s)+'px';
      o.caption.style.height = Math.round(o.gmt.s/o.gmt.ratio)*captionSizeFactor+'px';
      o.caption.style.borderWidth = Math.round(o.gmt.s*borderWidth/100)+'px';
      o.caption.style.fontSize = Math.round(o.gmt.s*fontSize/100)+'px';
      //if(o==show.focusedItem) opacity(o.caption,Math.min(((o.gmt.s/(show.wdw.w/gridNX/(mosaicSpacing+1))-1)*100)/(focusSizeFactor-1),100));
      //else opacity(o.caption,0);
      opacity(o.caption,o.gmt.op*100,100);
      
    }
  },

	run: function(){
		for(var i=0, item; item=show.items[i]; i++){
			show.process(item);
			show.draw(item);
		}
    if(show.destroy){
      if(show.items[0].gmt.s < (show.items[0].gmt.os)/10){
        document.location.href=show.link;
        show.destroy = false;
        return;
      }
    }
		setTimeout(show.run, 40);
	},

	resize: function(){
		show.wdw.w = show.wdw.element.offsetWidth;
		show.wdw.h = show.wdw.element.offsetHeight;
		container = show.wdw.element;
		for (show.wdw.x = 0, show.wdw.y = 0; container != null; container = container.offsetParent)
		{
			show.wdw.x += container.offsetLeft;
			show.wdw.y += container.offsetTop;
		}
		for(var y=0, i=0; y<gridNY; y++){
			for(var x=0; x<gridNX; x++){
        show.items[i].gmt.ox=(x-gridNX/2+0.5)*show.wdw.w/gridNX + show.wdw.w/2;
        show.items[i].gmt.oy=(y-gridNY/2+0.5)*show.wdw.h/gridNY + show.wdw.h/2;
        show.items[i].gmt.os=show.wdw.w/gridNX/(mosaicSpacing+1);
        show.items[i].img.className = 'unfocused';
        i++;
      }
    }
	}
}

var mouse={x: 0, y: 0};
document.onmousemove = function(e){
	if(window.event) e=window.event;
	mouse.x=e.clientX-show.wdw.x;
	mouse.y=e.clientY-show.wdw.y;
	return false;
}
onbeforeunload = function (){
  show.run();
}

