// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// encounter/control.js
//
// copyright (c) 2006-2010 drow <drow@bin.sh>
// all rights reserved.

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// configuration

var form = 'enc_form';
var rpc_url = '/d20/encounter/rpc.cgi';

var spot_dist = [
  '4d8 * 10', '1d8 * 10', '6d6 * 20', '6d6 * 10', '3d6 * 10',
  '2d8 * 10', '2d6 * 10', '2d10 * 10', '2d6 * 10', '6d6 * 10',
  '2d8 * 10', '4d10 * 10', '6d6 * 40', 'Line of sight and lighting'
];

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// format

var fmt = {
  'spot_dist':  '#{dist} ft. (#{dice})',
  'encounter':  '#{desc}<hr />#{monsters}',
  'p':          '<p>#{text}</p>'
};
Object.keys(fmt).each(function (key) {
  fmt[key] = new Template(fmt[key]);
});
fmt['working'] = '<p class="center">Working...</p>'
               + '<p class="center"><img src="/icons/loading.gif" /></p>';

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// initialize form

function init_form () {
  client_form(form);

  var form_elem = $(form).elements;
  var enc_prefs = get_cookie('enc') || {};
  var xp_prefs = get_cookie('xp') || {};

  if (value = enc_prefs.level) {
    setv(form_elem['level'],value);
  } else if (value = xp_prefs.pc_level) {
    setv(form_elem['level'],value);
  }
  if (value = enc_prefs.plane) setv(form_elem['plane'],value);
  if (value = enc_prefs.climate) setv(form_elem['climate'],value);
  if (value = enc_prefs.terrain) setv(form_elem['terrain'],value);
  if (value = xp_prefs.n_pc) setv(form_elem['n_pc'],value);
  if (value = xp_prefs.pc_level) setv(form_elem['pc_level'],value);

  locale_reaction();
  get_enc();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// set field

function set_field (field) {
  save_prefs('enc',field); get_enc();
}
function set_locale (field) {
  locale_reaction(); set_field(field);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// locale reaction

function locale_reaction () {
  var form_elem = $(form).elements;
  var plane = selv(form_elem['plane']);

  if (plane == '') {
    var terrain = selv(form_elem['terrain']);

    if (terrain == 'underground') {
      form_elem['climate'].disabled = true;
    } else {
      form_elem['climate'].disabled = false;
    }
  } else {
    form_elem['climate'].disabled = true;
  }
  var terrain_idx = form_elem['terrain'].selectedIndex;
  form_elem['spot'].value = get_spot_dist(terrain_idx);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// get spot distance

function get_spot_dist (idx) {
  var string = spot_dist[idx];

  if (string.match(/\d+d\d+/)) {
    var obj = { 'dice': string, 'dist': roll_dice(string) };
    return eval_fmt('spot_dist',obj);
  } else {
    return string;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// get random encounter

var encounter;

function get_enc () {
  var form_elem = $(form).elements;

  var query = { 'level': selv(form_elem['level']),
                'plane': selv(form_elem['plane']),
                'climate': selv(form_elem['climate']),
                'terrain': selv(form_elem['terrain']) };
  var opts = { 'method': 'get', 'parameters': query,
    'onSuccess': function (req) { got_enc(req); },
    'onFailure': function (req) { rpc_error(req.statusText); },
    'onException': function (req,err) { rpc_error('System Error'); } };

  new Ajax.Request(rpc_url,opts);
  $('out').update(fmt['working']);

  form_elem['actual_el'].value = '-';
  form_elem['total_xp'].value = '-';
  form_elem['xp_per_pc'].value = '-';
}
function got_enc (req) {
  if (req.responseJSON) {
    encounter = req.responseJSON;
  } else if (req.responseText) {
    encounter = req.responseText.evalJSON();
  } else {
    return rpc_error('No response');
  }
  var text = fmt_encounter(encounter);
  $('out').update(text);

  var el; if (el = encounter.el) {
    var form_elem = $(form).elements;
    form_elem['actual_el'].value = el;
    enc_xp();
  } else {
    form_elem['actual_el'].value = '-';
    form_elem['total_xp'].value = '-';
    form_elem['xp_per_pc'].value = '-';
  }
}
function rpc_error (text) {
  $('out').update(fmt_p(text));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// format encounter

function fmt_encounter (encounter) {
  var obj = {
    'desc':     fmt_text(encounter.desc),
    'monsters': fmt_monsters(encounter.monsters)
  };
  return eval_fmt('encounter',obj);
}
function fmt_monsters (list) {
  return list.map(fmt_monster).join('<hr />');
}
function fmt_monster (monster) {
  var text = fmt_text(monster.stat_block);
    if (loot = monster.treasure) text += fmt_text(loot);
  return text;
}
function fmt_text (text) {
  return text.split("\n\n").map(fmt_p).join('');
}
function fmt_p (text) {
  return eval_fmt('p',{ 'text': text });
}
function eval_fmt (fmt_id,obj) {
  return fmt[fmt_id].evaluate(obj);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// encounter xp

function enc_xp (field) {
  if (field) {
    save_prefs('xp',field);
  }
  var form_elem = $(form).elements;
  var list = encounter.monsters;

  var pc_l; if (pc_l = parseInt(selv(form_elem['pc_level']))) {
    var xp = 0; for (i = 0; i < list.length; i++) {
      var gang = list[i];
      xp += (gang.number * get_xp(pc_l,gang.cr));
    }
    form_elem['total_xp'].value = xp;

    var n_pc; if (n_pc = parseInt(selv(form_elem['n_pc']))) {
      var per_pc = Math.floor(xp / n_pc);
      form_elem['xp_per_pc'].value = per_pc;
    } else {
      form_elem['xp_per_pc'].value = '-';
    }
  } else {
    form_elem['total_xp'].value = '-';
    form_elem['xp_per_pc'].value = '-';
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// showtime

document.observe('dom:loaded',init_form);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

