var LARGE_PHOTO_PERCENTAGE = 0.25;
var MIN_OPACITY = 0.0; var BASE_OPACITY = 0.4; var MAX_OPACITY = 1.0;
var last_row = -1; var last_col = -1;
var actualDiv;
var files;

/* Startup functions */
function getLinkHTML(text, link)
{
  return "<a href=\"" + link + "\">" + text.slice(0, 1) + "<span style=\"font-size: 75%;\">" + text.slice(1) + "<\/span></a>";
}

function generateTextHTML(row, col, text)
{
  var top = row * 160 + 57;
  var left = col * 235 + 10; 

  var rval = "<div class=\"text\" style=\"top: " + top + "px; left: " + left + "px;\" \
               onmouseover='setOpacityIf(" + row + ", " + col + ", 1.0, BASE_OPACITY)' \
               onmouseout='setOpacityIf(" + row + ", " + col + ", BASE_OPACITY, MAX_OPACITY)'>";
  rval +=    "  " + text;
  rval +=    "</div>";
  return rval;
}

function fillPhotosArray()
{
  var oRequest = new XMLHttpRequest();
  var sURL  = "photos/files.txt";

  oRequest.open("GET", sURL, false);
  oRequest.setRequestHeader("User-Agent", navigator.userAgent);
  oRequest.send(null);

  files = new Array();
  if (oRequest.status == 200) {
    files = oRequest.responseText.split("\n");
  }
}

/* Mouse Over Function */
function getOpacity(row, col)
{
  var divid = getAdjustedDiv(row, col);
  
  if (document.getElementById(divid).style.opacity > 0)
    return document.getElementById(divid).style.opacity
  else
    document.getElementById(divid).style.filter.substring(15, document.getElementById(divid).style.filter.length - 1) * 1.0;
}

function setOpacityIf(row, col, value, test)
{
  if (getOpacity(row, col) == test)
    setOpacity(row, col, value);
}

/* Change Photos Functions */
function getRandomPhoto()
{
  return files[Math.floor(Math.random() * files.length)];
}

function generateSmallPhotoHTML(row, col, photo, opacity)
{
  actualDiv[row * 4 + col] = row * 4 + col;

  var top = row * 160;
  var left = col * 235;
  var rval = "";
  
  if (opacity == undefined)
    rval +=  "<div class=\"image_small\" id=\"d" + row + col + "\" style=\"top: " + top + "px; left: " + left + "px;\" \
              onmouseover='setOpacityIf(" + row + ", " + col + ", 1.0, BASE_OPACITY)' onmouseout='setOpacityIf(" + row + ", " + col + ", BASE_OPACITY, MAX_OPACITY)'>\n";
  else
    rval +=  "<div class=\"image_small\" id=\"d" + row + col + "\" style=\"top: " + top + "px; left: " + left + "px; opacity: " + opacity + "; filter: alpha(opacity = " + 100*opacity +");\" \
              onmouseover='setOpacityIf(" + row + ", " + col + ", 1.0, BASE_OPACITY)' onmouseout='setOpacityIf(" + row + ", " + col + ", BASE_OPACITY, MAX_OPACITY)'>\n";
  rval +=    "  <div>\n";
  rval +=    "    <img id=\"i" + row + col + "\" class=\"small\" src=\"photos/" + photo + "\" />\n";
  rval +=    "  </div>\n";
  rval +=    "</div>\n";

  return rval;
}

function generateBigPhotoHTML(row, col, photo, opacity)
{
  actualDiv[row * 4 + col] = row * 4 + col;
  actualDiv[(row + 1) * 4 + col] = row * 4 + col
  actualDiv[row * 4 + col + 1] = row * 4 + col;
  actualDiv[(row + 1) * 4 + col + 1] = row * 4 + col;

  var top = row * 160;
  var left = col * 235;
  var rval = "";
  if (opacity == undefined)
    rval +=  "<div class=\"image_large\" id=\"d" + row + col + "\" style=\"top: " + top + "px; left: " + left + "px;\" \
              onmouseover='setOpacityIf(" + row + ", " + col + ", 1.0, BASE_OPACITY)' onmouseout='setOpacityIf(" + row + ", " + col + ", BASE_OPACITY, MAX_OPACITY)'>\n";
  else
    rval +=  "<div class=\"image_large\" id=\"d" + row + col + "\" style=\"top: " + top + "px; left: " + left + "px; opacity: " + opacity + "; filter: alpha(opacity = " + 100*opacity +");\" \
              onmouseover='setOpacityIf(" + row + ", " + col + ", 1.0, BASE_OPACITY)' onmouseout='setOpacityIf(" + row + ", " + col + ", BASE_OPACITY, MAX_OPACITY)'>\n";
  rval +=    "  <div>\n";
  rval +=    "    <img id=\"i" + row + col + "\" class=\"large\" src=\"photos/" + photo + "\" />\n";
  rval +=    "  </div>\n";
  rval +=    "</div>\n";
 
  return rval;
}

function getAdjustedDiv(row, col)
{
  if (actualDiv[row * 4 + col] == row * 4 + col) {
    return "d" + row + col;
  } else {
    var divrow = Math.floor(actualDiv[row * 4 + col] / 4);
    var divcol = actualDiv[row * 4 + col] - divrow * 4;
    
    return "d" + divrow + divcol;
  }
}

function escapeQuotes(text)
{
  if (text != undefined)
    text = text.replace(/"/g, "\\\"");
  
  return text;
}

function fadeDivHelper(divid, current, result, up, func)
{
  if (up)
    current += 0.01;
  else
    current -= 0.01;
    
  setDividOpacity(divid, current)
  
  if (up && (current < result) || !up && (current > result))
    if (func == undefined)
      window.setTimeout("fadeDivHelper(\"" + divid + "\", " + current + ", " + result + ", " + up + ")", 50);
    else
      window.setTimeout("fadeDivHelper(\"" + divid + "\", " + current + ", " + result + ", " + up + ", \"" + escapeQuotes(func) + "\")", 50);
  else
    if (func != undefined)
      eval(func);
}

function setDividOpacity(divid, value)
{
  if (navigator.appName == "Microsoft Internet Explorer")
    document.getElementById(divid).style.filter = "alpha(opacity = " + 100 * value + ")";
  document.getElementById(divid).style.opacity = value;
}

function fadeDiv(divid, current, result, func)
{
  setDividOpacity(divid, current);
  
  if (current < result)
    fadeDivHelper(divid, current, result, 1, func);
  else
    fadeDivHelper(divid, current, result, 0, func);
}


function changeImage(row, col, photo)
{
  document.getElementById("i" + row + col).src = "photos/" + photo;
}

function removeDiv(row, col)
{
  document.getElementById("main").removeChild(document.getElementById("d" + row + col));
}

function setOpacity(row, col, opacity)
{
  setDividOpacity(getAdjustedDiv(row, col), opacity);
}

function resetOpacity(row, col)
{
  setOpacity(row, col, BASE_OPACITY);
}

function resetAllOpacities()
{
  for (var i = 0; i < 4; ++i)
    for (var j = 0; j < 4; ++j)
        resetOpacity(i, j);
}

function addAndFadeSmallPhotos(row, col)
{
  var i = row; var j = col;

  document.getElementById("main").innerHTML += generateSmallPhotoHTML(i, j, getRandomPhoto(), MIN_OPACITY);    
  fadeDiv("d" + i + j, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + i + ", " + j + ");");

  i++;
  document.getElementById("main").innerHTML += generateSmallPhotoHTML(i, j, getRandomPhoto(), MIN_OPACITY);    
  fadeDiv("d" + i + j, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + i + ", " + j + ");");

  j++;
  document.getElementById("main").innerHTML += generateSmallPhotoHTML(i, j, getRandomPhoto(), MIN_OPACITY);    
  fadeDiv("d" + i + j, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + i + ", " + j + ");");

  i--;
  document.getElementById("main").innerHTML += generateSmallPhotoHTML(i, j, getRandomPhoto(), MIN_OPACITY);    
  fadeDiv("d" + i + j, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + i + ", " + j + "); loadNewPhoto();");
}

function addAndFadeBigPhoto(row, col)
{
  document.getElementById("main").innerHTML += generateBigPhotoHTML(row, col, getRandomPhoto(), MIN_OPACITY);      
     
  fadeDiv("d" + row + col, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + row + ", " + col + "); loadNewPhoto();");
}

function fadeInPhoto(row, col)
{
  changeImage(row, col, getRandomPhoto()); 
  fadeDiv("d" + row + col, MIN_OPACITY, BASE_OPACITY, "resetOpacity(" + row + ", " + col + "); loadNewPhoto();");
}

function loadNewPhoto()
{
  do {
    var row = Math.floor(Math.random() * 3);
    var col = Math.floor(Math.random() * 3); 
      
    var divrow = Math.floor(actualDiv[row * 4 + col] / 4);
    var divcol = actualDiv[row * 4 + col] - divrow * 4;  
  } while (last_row == row && last_col == col)
  
  if (Math.random() < LARGE_PHOTO_PERCENTAGE &&
      (divrow != row || divcol != col || (divrow == row && divcol == col - 1) ||
        actualDiv[row * 4 + col] == row * 4 + col && 
        actualDiv[(row + 1) * 4 + col] == (row + 1) * 4 + col && 
        actualDiv[row * 4 + col + 1] == row * 4 + col + 1 &&
        actualDiv[(row + 1) * 4 + col + 1] == (row + 1) * 4 + col + 1 &&
        actualDiv[(row + 1) * 4 + col + 2] != (row + 1) * 4 + col + 1)) {
    //Fading in a large photo
    if (divrow != row || divcol != col || (divrow == row && divcol == col - 1)) {
      //Replace one large for one large
      fadeDiv("d" + divrow + divcol, BASE_OPACITY, MIN_OPACITY, "fadeInPhoto(" + divrow + ", " + divcol + ");");
    } else {
      //replace four small ones with a large
      fadeDiv("d" + row + col, BASE_OPACITY, MIN_OPACITY, "removeDiv(" + row + ", " + col + "); addAndFadeBigPhoto(" + row + ", " + col + ");");  row++;
      fadeDiv("d" + row + col, BASE_OPACITY, MIN_OPACITY, "removeDiv(" + row + ", " + col + ")");  col++;
      fadeDiv("d" + row + col, BASE_OPACITY, MIN_OPACITY, "removeDiv(" + row + ", " + col + ")");  row--;
      fadeDiv("d" + row + col, BASE_OPACITY, MIN_OPACITY, "removeDiv(" + row + ", " + col + ")");
    }
  } else {
    //Fading in small photo(s)
    if (divrow != row || divcol != col|| (divrow == row && divcol == col - 1)) {
      //replace a large one with four small ones
      var divid = "d" + divrow + divcol;
      fadeDiv(divid, BASE_OPACITY, MIN_OPACITY, "removeDiv(" + divrow + ", " + divcol + "); addAndFadeSmallPhotos(" + divrow + ", " + divcol + ");");
    } else {
      //Replace one small for one small
      var divid = "d" + row + col;
      fadeDiv(divid, BASE_OPACITY, MIN_OPACITY, "fadeInPhoto(" + divrow + ", " + divcol + ");");
    }
  }
}

function writeStatusMessage(message)
{
  document.getElementById("status").innerHTML += message + "<br>";
}