/* Global vars */

/* timers */
var changeTimer;
var fadeTimer;

/* arrays */
var imageList;
var tileList;
var tileOrdering;

function initTiles(imgIdxs, numtiles) {
   var i;

  /* Init the image list */
  imageList = new Array(imgIdxs.length);
  for (i = 0; i < imageList.length; i++) {
	imageList[i] = new tileImage(imgIdxs[i]);
  }

  /* Init the tile list */
  tileList = new Array(numtiles);
  tileOrdering = new Array(numtiles);
  for (i = 0; i < tileList.length; i++) {
	/* Load appropriate DOM objects */
	var aptr = document.getElementById("a"+i);
	var liptr = document.getElementById("li"+i);
	var imgptr = document.getElementById("img"+i);

	/* Get next image */
	var nextImage = imageList.shift();
	imageList.push(nextImage);
	nextImage.preload();
	
	tileList[i] = new tile(imgptr, aptr, liptr, nextImage.color, nextImage.bw);

	/* Make sure actual image is correct */
	liptr.style.backgroundImage = "url("+nextImage.bw+")";
	imgptr.src = nextImage.bw;

	/* Will be randomized later */
	tileOrdering[i] = tileList[i];
  }

  /* randomize tile ordering */
  randomizeArray(tileOrdering, 0, tileOrdering.length);
  
  /* Make sure next images are ready */
  imageList[0].preload();
  imageList[1].preload();
  imageList[2].preload();
  
  /* Start the timers */
  changeTimer = window.setInterval("doImageSwap()", 3500);
  startFadeTimer();
}

/* Timed functions */

function startFadeTimer() {
  if (!fadeTimer) {
   fadeTimer = window.setInterval("doAllFades()", 50);
  } 
}

function doAllFades() {
    var done = true;
    for (var i = 0; i < tileList.length; i++) {
        if (tileList[i].fade() == true) {
            done = false;
        }
    }

    if (done) {
        /* Nothing more to do, stop the timer */
        window.clearInterval(fadeTimer);
        fadeTimer = null;
    }
}

function doImageSwap() {
    var nextImage = imageList[0];
    
    /* Try 5 times to find a tile to swap */
    for (var i = 0; i < 5; i++) {
        tileOrdering.push(tileOrdering.shift());
        var nextTile = tileOrdering[0];
        if (nextTile.setimage(nextImage.color, nextImage.bw, nextImage.link) == true) {
            /* Success! */
            imageList.push(imageList.shift());
            
            /* Make sure next images are ready */
            imageList[0].preload();
            imageList[1].preload();
            imageList[2].preload();
            
            return;
        }
    }
}


/* Mouse event callbacks */

function mouseovertile(tilenum) {
    currIdx = tilenum;
    tileList[tilenum].colorize();
}

function mouseouttile(tilenum) {
    currIdx = null;
    tileList[tilenum].uncolorize();
}
 
/* Utilities */

/* Fisher-Yates randomize, with effective range */
function randomizeArray(myArray, from, to) {
    var i = to;
    while ( --i > from ) {
        var j = Math.floor(Math.random() * (i + 1));
        var tempi = myArray[i];
        var tempj = myArray[j];
        myArray[i] = tempj;
        myArray[j] = tempi;
    }
}

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;
}



/* Functions for managing individual tiles */

function tile(imgptr, aptr, liptr, colorimg, bwimg) {
    this.opacity = 0;
    this.busy = false;
    this.active = false;
    this.imgptr = imgptr;
    this.aptr = aptr;
    this.liptr = liptr;
    this.colorimg = colorimg;
    this.bwimg = bwimg;
    
    /* Add methods */
    this.setimage = setimage;
    this.colorize = colorize;
    this.uncolorize = uncolorize;
    this.fade = fade;
}

/* Transition a tile to a new image */
function setimage(newcolor, newbw, newlink) {
  /* Don't allow a new image if we're already in the process of a transition */
    if (this.busy || this.active) {
        return false;
    }

    /* Move bg image to fg at 100% opacity */
    this.imgptr.src = this.bwimg;
    this.opacity = 100;
    setOpacity(this.imgptr, this.opacity);
    
    /* Move new image to bg */
    this.liptr.style.backgroundImage = "url("+newbw+")";
    
    /* Set link */
    this.aptr.href = newlink;
    
    /* Record new values */
    this.colorimg = newcolor;
    this.bwimg = newbw;
    
    /* Start fade */
    this.busy = true;
    startFadeTimer();
    
    return true;
}

/* Transition a tile to the colorized version */
function colorize() {
    /* Mark as active */
    this.active = true;
    
    /* If we're currently in the process of a fade, kill it */
    this.busy = false;
    
    /* Make sure we have the proper fg and bg image */
    this.imgptr.src = this.colorimg;
    
    /* set opacity to 100 */
    this.opacity = 100;
    setOpacity(this.imgptr, this.opacity);
}

/* Transition a tile to the bw version */
function uncolorize() {
    /* Mark as active */
    this.active = false;
    
    
    /* Assumes fg image is already 100% color.  Good assumption? */
    this.busy = true;
    startFadeTimer();
}

/*
 Timed fade event handler
 May be called even if we're not fading
 Return whether we did anything
*/
function fade() {
    if (!this.busy) {
        /* We're not fading, so notify caller */
        return false;
    } 
    
    if (this.opacity > 0) {
        this.opacity -= 8;
        setOpacity(this.imgptr, this.opacity);
        return true;
    } else {
        /* Just in case ... */
        this.opacity = 0;
        setOpacity(this.imgptr, this.opacity);
        
        this.busy = false;
        return false;
    }
}

/* Container for tile images */
function tileImage(num) {
    this.color = "tiles/"+num+".jpg";
    this.bw = "tiles/"+num+"bw.jpg";
    this.link = "fresh/?p="+num;
    this.loaded = false;
    
    /* Methods */
    this.preload = preload;
}

function preload() {
    if (this.loaded == true) {
        return;
    }
    
    var colorImage = new Image;
    colorImage.src = this.color;

    var bwImage = new Image;
    bwImage.src = this.bw;
    
    this.loaded = true;
}

