road_mousemove = function (e) {
  if (!e) e = window.event;
  var x = e.layerX || e.offsetX;
  var y = e.layerY || e.offsetY;

  if (GAME_STATE == GS_NORMAL) {

  }
  else if (GAME_STATE == GS_ADDROAD) {
    if (this != BOARD.new_road) {
      BOARD.new_road.ok = false;
      BOARD.new_road.style.visibility = 'hidden';
    }
  }
  else if (GAME_STATE == GS_ADDSETT) {
    var v, left, top;

    switch (this.side) {
      case 0: v = (y < this.height/2) ? 0 : 5; break;
      case 1: v = (x < this.width/2) ? 0 : 1; break;
      case 2: v = (y < this.height/2) ? 1 : 2; break;
      case 3: v = (y < this.height/2) ? 2 : 3; break;
      case 4: v = (x < this.width/2) ? 4 : 3; break;
      case 5: v = (y < this.height/2) ? 5 : 4; break;
    }

    switch (v) {
      case 0: left = HEX_SIDE/2 - SETT_W/2 - 3; top = -2*SETT_H/3 + 1; break;
      case 1: left = HEX_SIDE*3/2 - SETT_W/2 + 1; top = -2*SETT_H/3 + 2; break;
      case 2: left = HEX_SIDE*2 - SETT_W/2 - 3; top = HEX_SIDE*SQRT_3/2 - 2*SETT_H/3 - 1; break;
      case 3: left = HEX_SIDE*3/2 - SETT_W/2 + 1; top = HEX_SIDE*SQRT_3 - 2*SETT_H/3 - 2; break;
      case 4: left = HEX_SIDE/2 - SETT_W/2 - 2; top = HEX_SIDE*SQRT_3 - 2*SETT_H/3; break;
      case 5: left = -SETT_W/2 + 1; top = HEX_SIDE*SQRT_3/2 - 2*SETT_H/3; break;
    }

    if (can_place_sett(this.hex, v)) {
      BOARD.new_sett.src = "img/sett-" + BOARD.new_sett.color + ".png";
      BOARD.new_sett.style.left = parseInt(this.hex.style.left) + left + "px";
      BOARD.new_sett.style.top = parseInt(this.hex.style.top) + top + "px";
      BOARD.new_sett.hex = this.hex;
      BOARD.new_sett.vertex = v;
      BOARD.new_sett.style.visibility = 'visible';
      BOARD.new_sett.ok = true;
    }
    else {
      BOARD.new_sett.style.visibility = 'hidden';
      BOARD.new_sett.ok = false;
    }
  }
  else if (GAME_STATE == GS_ADDCITY) {
    var v, left, top;

    switch (this.side) {
      case 0: v = (y < this.height/2) ? 0 : 5; break;
      case 1: v = (x < this.width/2) ? 0 : 1; break;
      case 2: v = (y < this.height/2) ? 1 : 2; break;
      case 3: v = (y < this.height/2) ? 2 : 3; break;
      case 4: v = (x < this.width/2) ? 4 : 3; break;
      case 5: v = (y < this.height/2) ? 5 : 4; break;
    }

    switch (v) {
      case 0: left = HEX_SIDE/2 - CITY_W/2 - 2; top = -2*CITY_H/3; break;   
      case 1: left = HEX_SIDE*3/2 - CITY_W/2 + 2; top = -2*CITY_H/3; break;
      case 2: left = HEX_SIDE*2 - CITY_W/2 - 2; top = HEX_SIDE*SQRT_3/2 - 2*CITY_H/3; break;
      case 3: left = HEX_SIDE*3/2 - CITY_W/2 + 2; top = HEX_SIDE*SQRT_3 - 2*CITY_H/3; break;
      case 4: left = HEX_SIDE/2 - CITY_W/2 - 2; top = HEX_SIDE*SQRT_3 - 2*CITY_H/3; break;
      case 5: left = -CITY_W/2 + 1; top = HEX_SIDE*SQRT_3/2 - 2*CITY_H/3 + 2; break;
    }

    if (can_place_city(this.hex, v)) {
      BOARD.new_city.src = "img/city-" + BOARD.new_city.color + ".png";
      BOARD.new_city.style.left = parseInt(this.hex.style.left) + left + "px";
      BOARD.new_city.style.top = parseInt(this.hex.style.top) + top + "px";
      BOARD.new_city.hex = this.hex;
      BOARD.new_city.vertex = v;
      BOARD.new_city.style.visibility = 'visible';
      BOARD.new_city.ok = true;
    }
    else {
      BOARD.new_city.style.visibility = 'hidden';
      BOARD.new_city.ok = false;
    }
  }
};


road_click = function (e) {
  if (!e) e = window.event;
  var x = e.layerX || e.offsetX;
  var y = e.layerY || e.offsetY;

  if (GAME_STATE == GS_NORMAL) {

  }
  else if (GAME_STATE == GS_ADDROAD) {
    if (this == BOARD.new_road && this.ok) save_road();
  }
  else if (GAME_STATE == GS_ADDSETT) {
    if (BOARD.new_sett.ok) save_sett();
  }
  else if (GAME_STATE == GS_ADDCITY) {
    if (BOARD.new_city.ok) save_city();
  }
};


function start_add_road () {
  if (GAME_STATE == GS_ADDROAD) {
    cancel_road();
    return;
  }
  else if (GAME_STATE != GS_NORMAL) {
    alert("You're busy doing something else!");
    return;
  }


  var sbox = $ID('road_color');
  var color = sbox.options[sbox.selectedIndex].value;

  if (REMAINING['road'][color] == 0) {
    alert("You don't have any roads left!");
    return;
  }

  if (! BOARD.setts[color]) {
    alert("You can't build any roads yet!");
    return;
  }

  REMAINING['road'][color]--;
  sbox.options[sbox.selectedIndex].text = color + " (" + REMAINING['road'][color] + ")";
  add_road(color);
}


function add_road (color) {
  if (GAME_STATE != GS_NORMAL) return;

  var img = $EL('IMG', '', 'road');
  img.color = color;
  img.onmousemove = road_mousemove;
  img.onclick = road_click;

  GAME_STATE = GS_ADDROAD;
  BOARD.appendChild(img);
  BOARD.new_road = img;
}


function cancel_road () {
  if (GAME_STATE != GS_ADDROAD) return;

  var sbox = $ID('road_color');
  var color = sbox.options[sbox.selectedIndex].value;
  REMAINING['road'][color]++;
  sbox.options[sbox.selectedIndex].text = color + " (" + REMAINING['road'][color] + ")";

  BOARD.removeChild(BOARD.new_road);
  GAME_STATE = GS_NORMAL;
}


function save_road () {
  if (GAME_STATE != GS_ADDROAD) return;
  var side = BOARD.new_road.side;
  var this_h = BOARD.new_road.hex;
  var adj_h = HEX_ADJACENCY[this_h.n-18][side];

  this_h.roads[side] = BOARD.new_road;
  if (adj_h) BOARD.zones[adj_h].roads[(side+3)%6] = BOARD.new_road;

  GAME_STATE = GS_NORMAL;
}


function can_place_road (hex, p) {
  if (hex.roads[p] != null) return false;

  // get end-points of the road
  var endpoints = [ VERTICES[hex.n-18][(p+5)%6], VERTICES[hex.n-18][p] ];

  // this road must touch another road of the same color
  // or a building of the same color
  // but if there is an opposing building at the end of the road
  // we're building off, we CAN'T build through it!

  for (var i = 0; i < 2; i++) {
    var ep = endpoints[i];
    var hexes = HEX_AT_VERTEX[ep];
    for (var h = 0; h < hexes.length; h++) {
      var hex_id = hexes[h];
      var r = BOARD.zones[hex_id[0]].roads[(hex_id[1]+i)%6];
      if (r != null && r.color == BOARD.new_road.color) {
        var s = BOARD.zones[hex_id[0]].setts[hex_id[1]];
        if (s == null || s.color == BOARD.new_road.color) return true;

        var c = BOARD.zones[hex_id[0]].cities[hex_id[1]];
        if (s == null && (c == null || c.color == BOARD.new_road.color)) return true;
      }

      var s = BOARD.zones[hex_id[0]].setts[hex_id[1]];
      if (s != null && s.color == BOARD.new_road.color) return true;

      var c = BOARD.zones[hex_id[0]].cities[hex_id[1]];
      if (c != null && c.color == BOARD.new_road.color) return true;
    }
  }

  return false;
}

