var mouseDownPos = null;

var Ship = Class.create({
  initialize: function(attributes) {
    this.attributes = attributes;

    var img = new Element('img', {
      src: '/images/ship.png'
    });

    var p = new Element('p', {
      class: 'name'
    }).insert(attributes.name || 'Ship ' + attributes.id);

    var sp = new Element('p', {
      class: 'speed'
    }).insert(attributes.speed);

    var hasnt_shot_indicator = new Element('img', {
      src: '/images/pistol.png',
      class: 'hasnt_shot_indicator'
    });
    if (!attributes.can_shoot) {
      hasnt_shot_indicator.hide();
    }

    var div = new Element('div', {
      id: 'ship_' + this.attributes.id,
      class: 'ship',
      style: 'left:' + (64 * attributes.x) + 'px;' + 'top:' + (64 * attributes.y) + 'px;'
    }).insert(img).insert(p).insert(sp).insert(hasnt_shot_indicator);

    $('battlefield').insert(div, 'bottom');
    Ship.all[attributes.id] = this;
  },

  domId: function() {
    return 'ship_' + this.attributes.id;
  },

  setSpeedAndShot: function(speed, can_shoot) {
    this.attributes.speed = speed;
    $(this.domId()).down().next().next().textContent = speed;
    var indicator = $(this.domId()).down('.hasnt_shot_indicator');
    if (can_shoot) {
      indicator.show();
    }
    else {
      indicator.hide();
    }
  },

  shoot: function(target) {
    new Ajax.Request('/combats/attack/' + this.attributes.id, {
      method: 'post',
      parameters: {
        target_id: target.attributes.id,
        'ship[x]': this.attributes.x,
        'ship[y]': this.attributes.y,
        'ship[speed]': this.attributes.speed
      }
    })
  },

  laserShoot: function(target) { // not tested prototype
    var x1 = (this.attributes.x + 0.5) * 64;
    var y1 = (this.attributes.y + 0.5) * 64;
    var x2 = (target.attributes.x + 0.5) * 64;
    var y2 = (target.attributes.y + 0.5) * 64;
    var dx = x2 - x1;
    var dy = y2 - y1;
    var d = Math.abs(dy) > Math.abs(dx) ? Math.abs(dy) : Math.abs(dx);
    var all = [];
    for (var i=0; i<d; i++) {
      var e = new Element('div', {class: 'pixel', style: 'left:' + (x1 + i / d * dx) + 'px;' +'top:' + (y1 + i / d * dy) + 'px'});
      all.push(e.identify());
      $('battlefield').insert(e);
    }
    new PeriodicalExecuter(function(pe) {
      pe.stop();
      for(i=0; i<all.size(); i++){
        $(all[i]).remove();
      }
    }, 0.5);
  },

  laserMiss: function(target) { // not tested prototype
    var x1 = (this.attributes.x + 0.5) * 64;
    var y1 = (this.attributes.y + 0.5) * 64;
    var x2 = (target.attributes.x) * 64;
    var y2 = (target.attributes.y) * 64;
    var dx = x2 - x1;
    var dy = y2 - y1;
    var d = Math.abs(dy) > Math.abs(dx) ? Math.abs(dy) : Math.abs(dx);
    var all = [];
    for (var i=0; i<d; i++) {
      var e = new Element('div', {class: 'pixel', style: 'background: yellow; left:' + (x1 + i / d * dx) + 'px;' +'top:' + (y1 + i / d * dy) + 'px'});
      all.push(e.identify());
      $('battlefield').insert(e);
    }
    new PeriodicalExecuter(function(pe) {
      pe.stop();
      for(i=0; i<all.size(); i++){
        $(all[i]).remove();
      }
    }, 0.5);
  },

  destroy: function() {
    $(this.domId()).remove();
    Ship.all[this.attributes.id] = undefined;
  },

  inspect: function() {
    return "Ship_#{id}_#{name}".interpolate(this.attributes);
  }
});
Ship.all = [];
Ship.selected = [];
Ship.destroyAll = function() {
  Ship.all.each(function(s) {
    if (s) {
      s.destroy();
    }
  });
};
Ship.idsAt = function(x1, y1, x2, y2) {
  var result = [];
  Ship.each(function(ship) {
    if ((ship.attributes.x >= x1) &&
    (ship.attributes.x <= x2) && 
    (ship.attributes.y >= y1) &&
    (ship.attributes.y <= y2)) {
      result.push(ship.attributes.id);
    }
  });
  return result;
}
Ship.select = function(ids) {
  ids.each(function(id) {
    var ship = Ship.all[id];
    if (!ship.attributes.enemy) {
      $(ship.domId()).addClassName('selected');
      Ship.selected.push(id);
    }
  });
  Ship.selected = Ship.selected.sort().uniq();
}
Ship.deselect = function(ids) {
  ids.each(function(id) {
    $(Ship.all[id].domId()).removeClassName('selected');
    Ship.selected = Ship.selected.without(id);
  });
}
Ship.deselectAll = function() {
  Ship.deselect(Ship.selected);
}
Ship.each = function(func) {
  var compacted = this.all.compact();
  if (compacted.length) {
    for (i = 0; i < compacted.length; i++) {
      func(compacted[i]);
    }
  }
}

// SHIP CLASS END

function shoot(weapon, action, ship_id, target_id) { // not tested prototype
  switch(action) {
    case 'hit': 
      Ship.all[ship_id].laserShoot(Ship.all[target_id]);
      Ship.all[ship_id].preview = undefined;
      Ship.all[target_id].preview = undefined;
      break;
    case 'miss':
      Ship.all[ship_id].laserMiss(Ship.all[target_id]);
      break;
    case 'destroy': Ship.all[target_id].destroy();
  }
}

function endTurn() {
  parameters = {};
  Ship.each(function(ship) {
    if (!ship.attributes.enemy) {
      parameters['ships[' + ship.attributes.id + '][speed]'] = ship.attributes.speed;
      parameters['ships[' + ship.attributes.id + '][x]'] = ship.attributes.x;
      parameters['ships[' + ship.attributes.id + '][y]'] = ship.attributes.y;
    }
  });
  new Ajax.Request('/combats/end_turn/'+Ship.combat_id, {asynchronous: true, evalScripts: true, method: 'post', parameters: parameters});
}

function endCombat(id) {
  window.location = '/combats/results/' + id;
}

function relativeEventCoordinates(event) {
  return relativeEventCoordinatesTo(event, battlefield);
}

function onMouseClick(event) {
  relative = relativeEventCoordinates(event);
  var x = Math.floor(relative.x / 64);
  var y = Math.floor(relative.y / 64);

  var found = Ship.idsAt(x, y, x, y);
  if (found.size() == 1) {
    var found_ship = Ship.all[found.first()];
    if (found_ship.attributes.enemy) {
      //shoot!!!
      if (Ship.selected.size() == 1) {
        var ship = Ship.all[Ship.selected.first()];
        ship.shoot(found_ship);
        $(ship.domId()).down('.hasnt_shot_indicator').hide();
      }
    }
    else {
      Ship.deselectAll();
      Ship.select(found);
    }
  }
  else if (found.size() == 0) {
    if (Ship.selected.size() == 1) {
      var ship = Ship.all[Ship.selected.first()];
      var decrease = Math.max(Math.abs(ship.attributes.x - x), Math.abs(ship.attributes.y - y));
      if (decrease <= ship.attributes.speed) {
        var div = $(ship.domId());
        div.setStyle({left: x * 64 + 'px', top: y * 64 + 'px'});
        ship.attributes.speed -= decrease;
        ship.attributes.x = x;
        ship.attributes.y = y;
        div.down().next().next().textContent = ship.attributes.speed;
      }
    }
  }
}

function onMouseDown(event) {
  if (event.isLeftClick()) {
    mouseDownPos = relativeEventCoordinates(event);
    event.stop();
  }
}

function onMouseUp(event) {
  if (event.isLeftClick()) {
    if (mouseDownPos) {
      if($('green_box')) {
        var mouseUpPos = relativeEventCoordinates(event);
        var x1 = Math.floor(Math.min(mouseDownPos.x, mouseUpPos.x) / 64);
        var y1 = Math.floor(Math.min(mouseDownPos.y, mouseUpPos.y) / 64);
        var x2 = Math.floor(Math.max(mouseDownPos.x, mouseUpPos.x) / 64);
        var y2 = Math.floor(Math.max(mouseDownPos.y, mouseUpPos.y) / 64);
        Ship.deselectAll();
        Ship.select(Ship.idsAt(x1, y1, x2, y2));
        $('green_box').remove();
      }
      mouseDownPos = null;
    }
    event.stop();
  }
}

function onContextMenu(event) {
  Ship.selected = [];
  Ship.each(function(ship) {
    $(ship.domId()).removeClassName('selected');
  });
  event.stop();
}

function onMouseMove(event) {
  var xy = relativeEventCoordinates(event);
  if (mouseDownPos) {
    var x1 = Math.min(mouseDownPos.x, xy.x);
    var x2 = Math.max(mouseDownPos.x, xy.x);
    var y1 = Math.min(mouseDownPos.y, xy.y);
    var y2 = Math.max(mouseDownPos.y, xy.y);
    if(!$('green_box')) {
      if (Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)) >= 8) {
        $('battlefield').insert(new Element('div', {id: 'green_box'}));
      }
    }
    var greenBox = $('green_box');
    if (greenBox) {
      greenBox.setStyle({
        left: x1 + 'px', 
        top: y1 + 'px',
        width: x2 - x1 + 'px',
        height: y2 - y1 + 'px'
      });
    }
  }
  else {
    var x = Math.floor(xy.x / 64);
    var y = Math.floor(xy.y / 64);
    var ids = Ship.idsAt(x, y, x, y);
    var id = ids[0];
    if (id) {
      if (typeof Ship.all[id].preview == 'string') {
        $('ship_preview').update(Ship.all[id].preview);
      }
      else if (!Ship.all[id].preview) {
        new Ajax.Request('/combats/show_ship/'+id+'.html', {method: 'get', 
        onComplete: function(response){updatePreview(response.responseText, id);}});
        Ship.all[id].preview = true;
      }
    }
  }
}

function updatePreview(text, index) {
  $('ship_preview').update(text);
  Ship.all[index].preview = text;
}

document.observe('dom:loaded', function() {
  battlefield = $('battlefield');
  if (battlefield) {
    battlefield.observe('click', onMouseClick);
    battlefield.observe('mousedown', onMouseDown);
    battlefield.observe('mouseup', onMouseUp);
    battlefield.observe('contextmenu', onContextMenu);
    battlefield.observe('mousemove', onMouseMove);
  }
});

