// debug - v0.3 - 6/8/2009
// http://benalman.com/projects/javascript-debug-console-log/
window.debug=(function(){var c=this,e=Array.prototype.slice,b=c.console,i={},f,g,j=9,d=["error","warn","info","debug","log"],m="assert clear count dir dirxml group groupEnd profile profileEnd time timeEnd trace".split(" "),k=m.length,a=[];while(--k>=0){(function(n){i[n]=function(){j!==0&&b&&b[n]&&b[n].apply(b,arguments)}})(m[k])}k=d.length;while(--k>=0){(function(n,o){i[o]=function(){var q=e.call(arguments),p=[o].concat(q);a.push(p);h(p);if(!b||!l(n)){return}b.firebug?b[o].apply(c,q):b[o]?b[o](q):b.log(q)}})(k,d[k])}function h(n){if(f&&(g||!b||!b.log)){f.apply(c,n)}}i.setLevel=function(n){j=typeof n==="number"?n:9};function l(n){return j>0?j>n:d.length+j<=n}i.setCallback=function(){var o=e.call(arguments),n=a.length,p=n;f=o.shift()||null;g=typeof o[0]==="boolean"?o.shift():false;p-=typeof o[0]==="number"?o.shift():n;while(p<n){h(a[p++])}};return i})();
var report = debug.log;  // mirrors Flash

$(document).ready(function() {
  $('#admin_console_border').mousedown(beginDrag);
  $(window).keydown(hideConsole);
});

var recipeCount = 0;
var recipeTimer;
function startRecipes()
{
  if(!$('#original_recipe'))  // not loaded yet
    setTimeout('startRecipes()', 1000);
  else {
    originalRecipe();
    recipeTimer = setInterval('originalRecipe()', 5*60*1000);
  }
}

function originalRecipe()
{
  if(++recipeCount >= 6)
    clearInterval(recipeTimer);
  $.getJSON("/recipe", function(recipe) {
    $('#original_recipe').html(recipe.recipe).attr("title", recipe.source);
  });
}
if(!developing)
  setTimeout('startRecipes()', 1000);

function makeIntoOneLine(elem)
{
  var height = elem.offsetHeight;
  var text = elem.innerHTML;
  elem.innerHTML = 'test';
  var normheight = elem.offsetHeight;
  elem.innerHTML = text;
  return shortenTextInElem(elem, normheight);
}

function shortenTextInElem(elem, targetheight) {
  var text = elem.innerHTML;
  var height = elem.offsetHeight;
  if (height > targetheight) {
    if (elem.title == '')
      {
	elem.title = text.replace(/(<([^>]+>))/ig, "");
	$(elem).data('full', text);
      }
    var words = text.split(' ');
    words.pop();
    text = words.shift();
    while(words.length != 0) {
      var word = words.shift();
      elem.innerHTML = text+' '+word+' ...';
      if (elem.offsetHeight > targetheight)
	break;
      text += ' '+word;
    }
    text += ' ...';
  }
  var same = elem.innerHTML = text;
  elem.innerHTML = text;
  return (height > targetheight && !same);
}

function makeGroupSingleLined(objects) {
  var has_multilines = true;
  var cycles = 0;
  while (has_multilines) {
    has_multilines = false;
    for (var i=0; i<objects.length; i++)
      if (makeIntoOneLine(objects[i]))
	has_multilines = true;
    cycles += 1;
    if (cycles > objects.length) break;
  }
}


function RGBtoHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);}
function toHex(N) {
 if (N==null) return "00";
 N=parseInt(N); if (N==0 || isNaN(N)) return "00";
 N=Math.max(0,N); N=Math.min(N,255); N=Math.round(N);
 return "0123456789ABCDEF".charAt((N-N%16)/16)
      + "0123456789ABCDEF".charAt(N%16);
}

function HexToR(h) {return parseInt((cutHex(h)).substring(0,2),16);}
function HexToG(h) {return parseInt((cutHex(h)).substring(2,4),16);}
function HexToB(h) {return parseInt((cutHex(h)).substring(4,6),16);}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7) : h;}

function switchToInnerTab(windowid, newtab, windowcontainer) {
  var sclass = "selectedinnertab";
  $('#innertabs div.'+sclass).removeClass(sclass);
  $(newtab).addClass(sclass);

  $('div.window', windowcontainer).addClass("hidden");
  $('#'+windowid).removeClass("hidden");
}

function makeUVLPParams(q) {
  var params = {};
  if(q.charAt(0) == "?") q = q.substr(1);
  jQuery.each(q.split('&'), function()
    {
      params[this.split('=')[0]] = this.split('=')[1];
    });
  return params;
}

function isAE500(response)
{
  return response.length > 500 && response.indexOf("The server encountered an error and could not complete your request.") != -1;
}

$.retried_ajax = function(type, url, data, success, delay) {
  delay = delay || 200;  // start retries at 200ms, doubling each time
  if(delay >= 1200000)
    return;  // no response after twenty minutes? quit (show giveup error msg?)
  if(!data) { // no extra params passed
    data = {};
    success = function() {};
  }
  else if(!success) { // missing success
    success = data;
    data = {};
  }

  $[type](url, data, function(response) {
    if(response == "timeout" || response == "retry" || isAE500(response))
      setTimeout(function() { $.retried_ajax(type,url,data,success,delay*2); },
		 delay);
    else if (response == "disabled") {
      window.location.href = '/disabled';
    }
    else
      success(response);
  });
};

// If you use two args, the second is treated as the success function instead.
// You can also just pass the URL.
$.retried_get = function(url, data, success) {
  $.retried_ajax("get", url, data, success);
};

$.retried_post = function(url, data, success) {
  $.retried_ajax("post", url, data, success);
};


function inversePct(num, total) {
  return parseInt((100 * (total - num)) / total) + "%";
}


function removeScreen() { $("#screen").fadeOut(500); }
function replaceScreen() { $("#screen").fadeIn(500); }

function logServerError(e) {
  var params = {'message':e.message,
		'fileName':e.fileName,
		'lineNumber':e.lineNumber,
		'stack':e.stack,
		'name':e.name};
  $.retried_get("j_error", params, function() {});
  debug.error("error!: ", params);
}


function clickWithin(e) {
  var jelem = $(e.target);
  if (jelem.hasClass("parent_clicker")) $('*',jelem).click();
}



// Admin console controls

var offsetX = 0;
var offsetY = 0;

function beginDrag(e) {
  var console = $('#admin_console');
  offsetX = e.pageX - parseInt(console.css('left'));
  offsetY = e.pageY - parseInt(console.css('top'));
  $('body').mousemove(drag).mouseup(endDrag);
  /*
  var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
  var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
  debug.log("( B e.pageX, e.pageY ) - " + pageCoords);
  debug.log("( B e.clientX, e.clientY ) - " + clientCoords);
   */
}

function drag(e) {
  /*
  var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
  var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
  debug.log("( D e.pageX, e.pageY ) - " + pageCoords);
  debug.log("( D e.clientX, e.clientY ) - " + clientCoords);
  */
  $('#admin_console')
    .css('left',e.pageX-offsetX+'px')
    .css('top',e.pageY-offsetY+'px');
}

function endDrag(e) {
  saveConsoleSettings();
  $('body').unbind("mousemove", drag).unbind("mouseup", endDrag);
}

function hideConsole(e) {
  if (e.keyCode==33 && e.shiftKey==1) {
    var console = $('#admin_console');
    console.toggleClass('hidden');
    saveConsoleSettings();
  }
}

function saveConsoleSettings() {
  var console = $('#admin_console');
  if (!console.is('*')) return;
  var params = { left:console.css('left'),
		 top:console.css('top'),
	         hidden:console.hasClass('hidden') };
  $.retried_get("/admin/saveconsoleparams",params,function() { ; });
}


/* Overlay */

var overlays = [];

function addOverlayBlock(query,html,pos) {
  overlays.push({query:query,html:html,pos:pos});
  $('#overlay_button').removeClass('hidden');
  // it's been broken, not sure how to fix, just hide it for now
  //$('#help_icon').removeClass('hidden');
}

function showOverlay() {
  if (!$.browser.msie || parseInt($.browser.version)>7)
    $('#overlay').height($(document).height());
  for (var i=0; i<overlays.length; i++) {
    var overlay = overlays[i];
    var block = $(overlay.query);
    if (block.length==0) continue;
    block = $(block[0]);
    if (block.hasClass('hidden')||block.hasClass('inback')||
        block.css('visibility')=='hidden') continue;
    makeOverlayBlock(block, overlay.html, overlay.pos);
  }
  $('#overlay, #overlay_close_button').show();
}

function hideOverlay() {
  $('.overlay_block, .overlay_info_block').remove();
  $('#overlay, #overlay_close_button').hide();
  $('#overlay_button .overlay_off').show();
  $('#overlay_button .overlay_on').hide();
  $('.overlay_item').removeClass('overlay_item');
}

function makeOverlayBlock(block, html, pos) {
  if (pos.indexOf('eval:')==0) pos = eval(pos.slice(5));

  var over_block = $('<div class="overlay_block"></div>');
  over_block.click(hideOverlay);

  var height_bits = ['padding-top','border-top-width',
		     'padding-bottom', 'border-bottom-width'];
  var width_bits = ['padding-left','border-left-width',
		     'padding-right', 'border-right-width'];

  var block_height = block.height();
  for (var i=0; i<height_bits.length; i++) {
    var size = parseInt(block.css(height_bits[i]));
    if (!isNaN(size)) block_height += size;
    //debug.log(height_bits[i]+' '+size);
  }

  var block_width = block.width();
  for (var j=0; j<width_bits.length; j++) {
    var size = parseInt(block.css(width_bits[j]));
    if (!isNaN(size)) block_width += size;
    //debug.log(width_bits[j]+' '+size);
  }
  if (block_width==0 || block_height==0) return;

  if (block[0].tagName=='TD') {
    over_block
      .css('height',block_height-3)
      .css('width',block_width-3)
      .css('top',block.offset().top)
      .css('left',block.offset().left);

    $('body').append(over_block);
  }
  else
    block.append(over_block);

  var info_block = $('<div class="overlay_info_block"></div>');
  var max_width = 400;
  if (pos=='right' || pos=='left')
    max_width = Math.min(max_width,700 - block_width - 80);
  info_block.html(html).css('max-width',max_width);
  $('body').append(info_block);

  if (pos=='below')
    info_block
      .css('top',block.offset().top + block_height + 20)
      .css('left',block.offset().left);

  else if (pos=='above')
    info_block
      .css('top',block.offset().top - info_block.height() - 40)
      .css('left',block.offset().left);

  else if (pos=='right')
    info_block
      .css('top',block.offset().top)
      .css('left',block.offset().left + block_width + 20);

  else
    info_block
      .css('top',block.offset().top)
      .css('left',block.offset().left - info_block.width() - 40);

  var content = $('#content_wrapper');
  var max_left = content.offset().left + content.width() - info_block.width();
  max_left -= 20;
  info_block.css('left',Math.min(parseInt(info_block.css('left')),max_left));

  var max_top = content.offset().top + content.height() - info_block.height();
  max_top -= 20;
  info_block.css('top',Math.min(parseInt(info_block.css('top')),max_top)),

  over_block
    .mouseover(function() {
      info_block.css('visibility','visible').hide().fadeIn(200); })
    .mouseout(function() {
      info_block.fadeOut(200); });

  block.addClass('overlay_item');
  if (block.css('position')!='absolute') block.css('position','relative');
  //$('*',block).css('z-index',101).css('position','relative');
}


function toggleListActivated(checkbox) {
  $('div.list_msg').remove();

  var activated = $(checkbox).attr('checked');
  var parent = checkbox;
  try { while (parent.tagName != "TR") parent = parent.parentNode; }
  catch (e) { parent = null; debug.log("except!"); }
  if ( parent!=null ) {
    parent = $(parent);
    if (activated) parent.addClass("selected");
    else parent.removeClass("selected");
  }

  checkbox = $(checkbox);
  var params = {listkey:checkbox.val(), active:activated};
  $.retried_post("/vocab/setuvlp", params, function() {} );

  var msg_box = $('<div class="list_msg"></div>');
  msg_box.addClass((activated) ? "list_msg_act" : "list_msg_dea");
  msg_box.text((activated) ?
	       "Saved: words will be added from this list while practicing." :
	       "Saved: words are not being added from this list.");
  msg_box
    .css('left',checkbox.offset().left+160)
    .css('top',checkbox.offset().top-2);
  $('body').append(msg_box);

  setTimeout(function() { msg_box.fadeOut(1000); }, 2000);
  setTimeout(function() { msg_box.remove(); }, 3000);

}


var to_replace = [['C','Character'],['D','Definition'],['T','Tone'],
		  ['P','Pinyin'],   ['K','Kanji'],     ['R','Reading']];
for (var i=0; i<to_replace.length; i++)
  to_replace[i][1] = ('<span title="'+to_replace[i][1]+'">'+
		      to_replace[i][0]+'</span>');

function addPartTitles(elems) {
  elems.each(function()
  {
    var cell = $(this);
    var html = cell.html();
    if (html.indexOf('span')>-1) return true;
    for (var i=0; i<to_replace.length; i++)
      html = html.replace(to_replace[i][0], to_replace[i][1]);
    cell.html(html);
  });
}

// builds login form

function loginProcess() {

  // This is an attempt to fix the bug in chrome where users cannot log in
  loadjscssfile('/js/md5.js','js');

  try {
    var p = $('#loginform #id_password');
    if (p.val().slice(0,5)=='hash:' || p.val()=='') return;
    var salt = $('#loginform #id_salt').val();
    p.val("hash:"+hex_md5(p.val() + salt));
  }
  catch (e) {
    $('#screen p').text("Javascript error. We're working on it.");
    replaceScreen();
    logServerError(e);
    return false;
  }
  $('#signindiv label').remove();
  return true;
}


function loadjscssfile(filename, filetype){
 if (filetype=="js"){ //if filename is a external JavaScript file
   var fileref=document.createElement('script');
   fileref.setAttribute("type","text/javascript");
   fileref.setAttribute("src", filename);
 }
 else if (filetype=="css"){ //if filename is an external CSS file
   var fileref=document.createElement("link");
   fileref.setAttribute("rel", "stylesheet");
   fileref.setAttribute("type", "text/css");
   fileref.setAttribute("href", filename);
 }
 if (typeof fileref!="undefined")
   document.getElementsByTagName("head")[0].appendChild(fileref);
}
