




function toggleRedPlayer() {

  if (document.forms.playersForm.RedEnabled.checked) {
    document.forms.playersForm.RedName.disabled = false;
    if (document.forms.playersForm.RedName.value == "") {
      document.forms.playersForm.RedName.value = "Red player";
    }
  } else {
    document.forms.playersForm.RedName.disabled = true;
  }

}

function toggleYellowPlayer() {

  if (document.forms.playersForm.YellowEnabled.checked) {
    document.forms.playersForm.YellowName.disabled = false;
    if (document.forms.playersForm.YellowName.value == "") {
      document.forms.playersForm.YellowName.value = "Yellow player";
    }
  } else {
    document.forms.playersForm.YellowName.disabled = true;
  }

}

function toggleGreenPlayer() {

  if (document.forms.playersForm.GreenEnabled.checked) {
    document.forms.playersForm.GreenName.disabled = false;
    if (document.forms.playersForm.GreenName.value == "") {
      document.forms.playersForm.GreenName.value = "Green player";
    }
  } else {
    document.forms.playersForm.GreenName.disabled = true;
  }

}

function toggleBluePlayer() {

  if (document.forms.playersForm.BlueEnabled.checked) {
    document.forms.playersForm.BlueName.disabled = false;
    if (document.forms.playersForm.BlueName.value == "") {
      document.forms.playersForm.BlueName.value = "Blue player";
    }
  } else {
    document.forms.playersForm.BlueName.disabled = true;
  }

}

function validatePlayers() {

  if (document.forms.playersForm.RedEnabled.checked) {
    if (document.forms.playersForm.RedName.value.length == 0) {
      alert("Please enter a name for the red player.");
      return 0;
    }
  }

  if (document.forms.playersForm.YellowEnabled.checked) {
    if (document.forms.playersForm.YellowName.value.length == 0) {
      alert("Please enter a name for the yellow player.");
      return 0;
    }
  }

  if (document.forms.playersForm.GreenEnabled.checked) {
    if (document.forms.playersForm.GreenName.value.length == 0) {
      alert("Please enter a name for the green player.");
      return 0;
    }
  }

  if (document.forms.playersForm.BlueEnabled.checked) {
    if (document.forms.playersForm.BlueName.value.length == 0) {
      alert("Please enter a name for the blue player.");
      return 0;
    }
  }

  var playerCount = document.forms.playersForm.RedEnabled.checked + document.forms.playersForm.YellowEnabled.checked + document.forms.playersForm.GreenEnabled.checked + document.forms.playersForm.BlueEnabled.checked;

  if (playerCount < 2) {
    alert("At least two players are needed for Snakes and Ladders.");
    return 0;
  }

  return playerCount;

}





function PlayerObject(n, c) {
  this.name = n;
  this.colourName = c;
  this.position = 1;
  this.destination = 1;
}

function ShortcutObject(from, to, l) {
  this.fromPosition = from;
  this.toPosition = to;
  this.lengthType = l;
}

function getMidiName(s) {
  return shortcutType(s) + s.lengthType;
}

function shortcutType(shortcut) {
  if (shortcut.fromPosition < shortcut.toPosition) {
    return "ladder";
  } else {
    return "snake";
  }
}

function getBoardX(n) {
  if (getBoardY(n) % 2 == 1) {
    return (n-1) % 10;
  } else {
    return 9 - (n-1) % 10;
  }
}

function getBoardY(n) {
  return 9 - Math.floor( (n-1) / 10 );
}

function getOffsetX(colour) {
  if (colour == "red") {
    return 2;
  } else if (colour == "yellow") {
    return -2;
  } else if (colour == "green") {
    return 11;
  } else if (colour == "blue") {
    return 6;
  }
}

function getOffsetY(colour) {
  if (colour == "red") {
    return 4;
  } else if (colour == "yellow") {
    return 2;
  } else if (colour == "green") {
    return -2;
  } else if (colour == "blue") {
    return -4;
  }
}




var shortcutCount = 20;
var shortcuts = new Array(shortcutCount);

// ladders
shortcuts[0] = new ShortcutObject(4, 24, "med"); 
shortcuts[1] = new ShortcutObject(8, 34, "long"); 
shortcuts[3] = new ShortcutObject(22, 42, "med"); 
shortcuts[2] = new ShortcutObject(30, 31, "short"); 
shortcuts[4] = new ShortcutObject(25, 73, "xlong"); 
shortcuts[5] = new ShortcutObject(44, 78, "long"); 
shortcuts[6] = new ShortcutObject(60, 61, "short"); 
shortcuts[7] = new ShortcutObject(72, 93, "med"); 
shortcuts[8] = new ShortcutObject(85, 96, "short"); 
shortcuts[9] = new ShortcutObject(49, 53, "short");

// snakes
shortcuts[10] = new ShortcutObject(15, 5, "short"); 
shortcuts[11] = new ShortcutObject(32, 9, "long"); 
shortcuts[12] = new ShortcutObject(35, 18, "long"); 
shortcuts[13] = new ShortcutObject(38, 20, "med"); 
shortcuts[14] = new ShortcutObject(65, 26, "long"); 
shortcuts[15] = new ShortcutObject(94, 33, "xlong"); 
shortcuts[16] = new ShortcutObject(58, 41, "med"); 
shortcuts[17] = new ShortcutObject(90, 69, "med"); 
shortcuts[18] = new ShortcutObject(81, 63, "med"); 
shortcuts[19] = new ShortcutObject(98, 64, "long"); 

var players = new Array(4);
var playerCount;
var i;
var k;
var roll;
var animationframes;
var interval;
var defaultFrames = 20;
var s;
var diceEnabled = false;
var manual = false;
var expert = false;
var tempDestination = 1;
var paused = false;
var round = 0;


function startGame() {

  i = 0;
  playerCount = validatePlayers();
  
  if (playerCount < 2) {
    return;
  }

  document.forms.playersForm.StartGameButton.disabled = true;

  animationframes = defaultFrames;
  interval = document.forms.playersForm.GameSpeed.value;

  if (document.forms.playersForm.RedEnabled.checked) {
    players[i] = new PlayerObject(document.forms.playersForm.RedName.value, "red");
    if (interval > 0) {
      slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
    } else {
      moveTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName));
    }
    i++;
  }

  if (document.forms.playersForm.YellowEnabled.checked) {
    players[i] = new PlayerObject(document.forms.playersForm.YellowName.value, "yellow");
    if (interval > 0) {
      slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
    } else {
      moveTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName));
    }
    i++;
  }

  if (document.forms.playersForm.GreenEnabled.checked) {
    players[i] = new PlayerObject(document.forms.playersForm.GreenName.value, "green");
    if (interval > 0) {
      slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
    } else {
      moveTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName));
    }
    i++;
  }

  if (document.forms.playersForm.BlueEnabled.checked) {
    players[i] = new PlayerObject(document.forms.playersForm.BlueName.value, "blue");
    if (interval > 0) {
      slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
    } else {
      moveTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName));
    }

    i++;
  }

  manual = document.forms.playersForm.manualBox.checked;
  diceEnabled = false;
  expert = false;
  if (document.forms.playersForm.GameMode.value == "expert") {
    expert = true;
  }

  if (manual) {
    document.forms.playersForm.PauseGameButton.disabled = true;
  } else {
    document.forms.playersForm.PauseGameButton.disabled = false;
  }

  document.forms.playersForm.GameProgress.value = "";
  i = playerCount - 1;
  if (interval > 0) {
    setTimeout("continueGame();", (animationframes + defaultFrames) * interval);
  } else {
    continueGame();
  }
}





function continueGame() {


  // check for a move still in progress
  if (players[i].position != players[i].destination) {

    if (players[i].position == 100) {
      players[i].destination = 100 - (players[i].destination - 100);
    }

    if (players[i].position < players[i].destination) {
      players[i].position += 1;
    } else {
      players[i].position -= 1;
    }
    animationframes = defaultFrames;


    if (interval > 0) {
      slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
      setTimeout("continueGame();", (animationframes + defaultFrames) * interval);
    } else {
      continueGame();
    }


  // check for victory
  } else if (players[i].position == 100) { 


    if (interval == 0) {
      for (k = 0; k < playerCount; k++) {
   	  moveTo(players[k].colourName, getLeft("board") + 42 * getBoardX(players[k].position) + getOffsetX(players[k].colourName), getTop("board") + 42 * getBoardY(players[k].position) + getOffsetY(players[k].colourName));
      }
    }

    document.forms.playersForm.GameProgress.value = document.forms.playersForm.GameProgress.value + "The game has ended after " + round + " rounds. The winner is " + players[i].name + "!\n";
    document.forms.playersForm.GameProgress.scrollTop = document.forms.playersForm.GameProgress.scrollHeight;

    if (document.forms.playersForm.musicBox.checked) {
      playSoundEffect('victory');
    }

    document.forms.playersForm.StartGameButton.disabled = false;
    diceEnabled = false;



  } else { 


    // check for snakes and ladders
    for (k = 0; k < shortcutCount; k++) {

      if (players[i].position == shortcuts[k].fromPosition ) {

        animationframes = defaultFrames * Math.sqrt(Math.pow(getBoardX(players[i].position)-getBoardX(shortcuts[k].toPosition),2)+Math.pow(getBoardY(players[i].position)-getBoardY(shortcuts[k].toPosition),2));
        players[i].position = shortcuts[k].toPosition;
        players[i].destination = shortcuts[k].toPosition;
        document.forms.playersForm.GameProgress.value = document.forms.playersForm.GameProgress.value + players[i].name + " has hit a " + shortcutType(shortcuts[k]) + " and moves to " + players[i].position + "!\n";

	  document.forms.playersForm.GameProgress.scrollTop = document.forms.playersForm.GameProgress.scrollHeight;

        if (document.forms.playersForm.musicBox.checked) {
          playSoundEffect(getMidiName(shortcuts[k]));
   	  }

        if (interval > 0) {
          slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
          setTimeout("continueGame();", (animationframes + defaultFrames) * interval);
        } else {
          continueGame();
        }

        break;
      }
    }

    // if there were no snakes or ladders, we can move on to the next player
    if (k == shortcutCount) {
      i = (i + 1) % playerCount;

      if (i == 0) {
        round++;
        document.forms.playersForm.GameProgress.value = document.forms.playersForm.GameProgress.value + "   Round " + round + ":\n";
	  document.forms.playersForm.GameProgress.scrollTop = document.forms.playersForm.GameProgress.scrollHeight;
      }

      document.playerImage.src = players[i].colourName + ".gif";
      document.forms.playersForm.GameProgress.value = document.forms.playersForm.GameProgress.value + "It's " + players[i].name + "'s turn!\n";
	document.forms.playersForm.GameProgress.scrollTop = document.forms.playersForm.GameProgress.scrollHeight;
	if (manual) {
	  diceEnabled = true;
      } else {
        if (paused) {
          document.forms.playersForm.PauseGameButton.disabled = false;
        } else {
          startNextTurn();
        }
      }
    }

  }

}





function diceClick() {
  if (diceEnabled) {
    setTimeout("startNextTurn();", defaultFrames * interval);
    document.dice.src = "rolling.gif";
  }
}




function startNextTurn() {
      diceEnabled = false;
      roll = Math.floor(Math.random()*6) + 1;
      document.dice.src = roll + ".gif";
      players[i].destination = players[i].position + roll;
	players[i].position += 1;

	tempDestination = players[i].destination;
      if (tempDestination > 100) {
	  if (expert) {
  	    tempDestination = 100 - (tempDestination - 100);
        } else {
	    tempDestination = 100;
	    players[i].destination = 100;
	  }
      }
      
      document.forms.playersForm.GameProgress.value = document.forms.playersForm.GameProgress.value + players[i].name + " rolls " + roll + " and moves to " + tempDestination + ".\n";
	document.forms.playersForm.GameProgress.scrollTop = document.forms.playersForm.GameProgress.scrollHeight;
      animationframes = defaultFrames;
      if (interval > 0) {
        slideTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName), animationframes, interval);
        setTimeout("continueGame();", (animationframes + defaultFrames) * interval);
      } else {
	  if (manual) {
          moveTo(players[i].colourName, getLeft("board") + 42 * getBoardX(players[i].position) + getOffsetX(players[i].colourName), getTop("board") + 42 * getBoardY(players[i].position) + getOffsetY(players[i].colourName));
	  }
        continueGame();

      }
}



function playSoundEffect(sound) {
  top.soundframe.location = "sound.html?sound="+sound;
}




function pauseGame() {
  if (!manual) {
    if (paused) {
      paused = false;
      startNextTurn();
    } else {
      paused = true;
      document.forms.playersForm.PauseGameButton.disabled = true;
    }
  }
}




// ANIMATION

function getLeft(id) {
  if (NS4) {
    return eval("document."+id+".left;");
  } else if (IE4) {
    return parseInt(eval("document.all."+id+".style.left;"));
  } else if (DOM) {
    return parseInt(document.getElementById(id).style.left);
  }
}

function getTop(id) {
  if (NS4) {
    return eval("document."+id+".top;");
  } else if (IE4) {
    return parseInt(eval("document.all."+id+".style.top;"));
  } else if (DOM) {
    return parseInt(document.getElementById(id).style.top);
  }
}

function moveTo(id, x, y) {
  if (NS4) {
    eval("document."+id+".left=x;");
    eval("document."+id+".top=y;");
  } else if (IE4) {
    eval("document.all."+id+".style.left=x;");
    eval("document.all."+id+".style.top=y;");
  } else if (DOM) {
    document.getElementById(id).style.left=x+"px";
    document.getElementById(id).style.top=y+"px";
  }
}

function step(id, fromx, fromy, tox, toy, i, steps, delay) {
  if (i <= steps) {
    moveTo(id, Math.round(fromx + (i / steps) * (tox - fromx)), Math.round(fromy + (i / steps) * (toy - fromy)));
    setTimeout("step('"+id+"', "+fromx+", "+fromy+", "+tox+", "+toy+", "+(i+1)+", "+steps+", "+delay+");",delay);
  }
}

function slideTo(id, x, y, steps, delay) {
  step(id, getLeft(id), getTop(id), x, y, 0, steps, delay);
}



