var loading = false;
var clickedLink = false;
var collapsed = true;


// -------------------------------------------------------------------
// META DATA AND ACTIONBAR

/*
function setListStatus(status) {
  //$("#activate_button").attr("disabled",(status!="stop"));
  //$("#deactivate_button").attr("disabled",(status=="stop"));
  if (status=="stop") {
    $('#activated_text').addClass('hidden');
    $('#deactivated_text').removeClass('hidden');
  }
  else {
    $('#activated_text').removeClass('hidden');
    $('#deactivated_text').addClass('hidden');
  }

  saveAddListSettings();
}
var action_div_hidden = true;
function toggleMoreActionsDiv() {
  action_div_hidden = !action_div_hidden;
  if (action_div_hidden) {
    $("#more_actions").fadeOut(200);
  }
  else {
    $("#more_actions").fadeIn(200);
  }
}

function getListStatus() {
  return ($('#activated_text').hasClass('hidden')) ? 'stop' : 'play';
}

var lastparams = null;
var sentparams = null;

function saveAddListSettings() {
  // build the parameters
  var params = { skipping: getSectionsSkippedIndexes(),
		 sect: 0,
		 status: getListStatus(),
		 list: listviewing
	       };

  var sect = $("#addsectiontable input:checked");
  if (sect.length>0) params.sect = sect.val();

  // don't send off save requests all at once, save for later if needed
  lastparams = params;
  if (sentparams != null) return;
  else sentparams = params;

  $.retried_post('savelist', params, function()
    {
      // try again if the buttons have changed since the AJAX call started
      if (lastparams != sentparams)
	setTimeout(saveAddListSettings, 200);
      lastparams = null;
      sentparams = null;
    });

  highlightActiveRow();
}


function highlightActiveRow() {
  $('#addsectiontable tr.selected').removeClass('selected');
  var radio = $('#addsectiontable input:checked');
  if (radio.length>0) {
    var parent = radio[0];
    try { while (parent.tagName != "TR") parent = parent.parentNode; }
    catch (e) { parent = null; }
    if (parent!=null) $(parent).addClass('selected');
  }
}

*/

function parseTag() {
  var tag_input = $('#tag_input');
  var names = tag_input.val().split(',');
  for (var i=0; i<names.length; i++) {
    var name = names[i];
    if (name=='') continue;
    var params = {action:'add',name:name, list:listviewing };
    tag_input.val('');
    $.retried_post('/vocab/list/edittag', params, function(response)
      {
	var name = $.parseJSON(response).name;
	if (name) addTag(name, true);
      });
  }
}

function addTagKeyPress(event) {
  debug.log(event.keyCode);
}

function addTag(name, sort) {
  var link = $('<a href="/vocab/tags?tag='+name+'">'+name+'</a>');
  var remove = $('<span class="tag_remove clickable" onclick="if (confirm(\'Remove this tag?\')) removeTag(this);">x</span>');
  var tag = $('<span class="tag"> </span> ');
  tag.append(link).append(remove).append(' ');
  var tags = $('#tags .tag');
  var added = false;
  for (var i=0; i<tags.length; i++) {
    if (!sort) break;
    var existing_tag = $(tags[i]);
    if (name < $('a',existing_tag).text()) {
      existing_tag.before(tag);
      added = true;
      break;
    }
  }
  if (!added) $('#tags').append(tag);
  $('#no_tags').hide();
}

function removeTag(obj) {
  var tag = $(obj.parentNode);
  var tagname = $('a',tag).text();
  var params = { action:'remove', name:tagname, list:listviewing };
  $.retried_post('/vocab/list/edittag', params, function(response)
    {
      tag.remove();
      if ($('.tag').length==0) $('#no_tags').show();
    });
}

function closeSubmitBoxCallback(e) {
  if ($(e.target).closest('#tagSubmitBox').length==1 ||
      $(e.target).closest('#tag_edit').length==1) return;
  toggleEditTags();
}

var tagsEditable = false;
function toggleEditTags() {
  tagsEditable = !tagsEditable;
  if (tagsEditable) {
    $('body').click(closeSubmitBoxCallback);
    $('#tagSubmitBox').removeClass('hidden');
  }
  else {
    $('body').unbind('click', closeSubmitBoxCallback);
    $('#tagSubmitBox').addClass('hidden');
  }
}

/*
function toggleMoreActions() {
  $('#more_actions').toggleClass('hidden');
}

function mouseClickCloseMoreActions(e) {
  var elem = e.target;
  try {
    while ($(elem).attr('id') != 'more_actions' &&
	   $(elem).attr('id') != 'more_actions_button')
      elem = elem.parentNode;
  }
  catch (e) { $('#more_actions').addClass('hidden'); }
  return;
}
*/



// -------------------------------------------------------------------
// VOCAB LIST BROWSER


// ---------- top controls: collapse, style and section

function selectSelectedRows() {
  $("#list_browser tr.vocabrow").each(function()
    {
      if ($.inArray(this.id, selected_keys) != -1)
	$(this).addClass("selected");
      else
	$(this).removeClass("selected");
    });
}

function shortenBrowserLines() {
  makeGroupSingleLined($("#list_browser span"));
}

var res = null;
var fetchinguis = false;
function fetchUserItemProgresses()
{
  if (fetchinguis) return;
  fetchinguis = true;

  // build a list of vocabs yet to do
  var vocabs = [];
  $("#vocab_list_table tr.stub").each(function()
    { vocabs.push($(this).attr("id")); });

  // see if the work is done
  if (vocabs.length==0) {
    fetchinguis = false;
    addPartTitles($('td.uidiv'));
    return;
  }

  var params = { vocabs: vocabs.splice(0,5) };
  $.retried_get("getuiprogressdata", params, function(response)
    {
      fetchinguis = false;

      if (response=="stop") return;
      response = $.parseJSON(response);

      for (var j in response.vocabs) {
	var key = response.vocabs[j];
	var rows = $("tr[id='"+key+"']");
	rows.removeClass("stub");
      }
      res = response.uidata;

      // put the data into the appropriate rows
      for (var i in response.uidata) {
	var uidata = response.uidata[i];
	var rows = $("tr[id='"+uidata.vocabkey+"']");
	var cells = $('td.'+uidata.part, rows)
		      .css('background',uidata.color)
		      .text(uidata.part);
	if (uidata.enabled=="True"||uidata.enabled==true)
	    cells.addClass("existing_ui");
      }

      fetchUserItemProgresses(); // repeat
    });
}




// ---------- selection functions

var selected_keys = new Array();

function toggleSelectAll() {
  if (loading) return;
  var rows = $("#vocab_list_table tr.vocabrow");
  var not_selected = rows.filter(":not(.selected)");
  if (not_selected.length > 0)
    rows = not_selected;
  rows.each(function() { toggleSelect(this); });
}

function toggleSelect(div)
{
  if (loading) return;
  if (clickedLink) { clickedLink = false; return; }

  var parts = '';
  $('.uidiv',div).each(function() { parts += $(this).text(); });
  if ($(div).hasClass("selected")) removeLetter(div.id,parts);
  else addLetter(div.id,parts);
  $(div).toggleClass("selected");
  displayNumSelected();
}

function selectNone() {
  if (loading) return;
  selected_keys = [];
  displayNumSelected();
  selectSelectedRows();
}

function addLetter(key, parts)
{
  var data = key + "_" + parts;
  if ($.inArray(data, selected_keys) != -1)
    return false;
  selected_keys.push(data);
  return true;
}

function removeLetter(key, parts)
{
  var data = key + "_" + parts;
  var index = $.inArray(data, selected_keys);
  if (index == -1)
    return false;
  selected_keys.splice(index, 1);
  return true;
}

function displayNumSelected()
{
  try { $("#added_num").text(selected_keys.length); }
  catch (e) { }
}




// ---------- add and delete buttons

var total = null;
function addSelectedToQueue() { submitSelection('add'); }
function deleteSelected() { submitSelection('delete'); }

function submitSelection(url) {
  if (total == null) { total = selected_keys.length; }
  if (selected_keys.length==0) {
    total = null;
    fetchUserItemProgresses();
    return;
  }
  $('#vocab_list_table tr.selected').addClass('stub');
  $('tr.selected td.existing_ui').removeClass('existing_ui');

  var datas = selected_keys[0].split('_');
  var params = { key:datas[0] };
  $.retried_post(url, params, function(response)
    {
      if (response != "error") {
	$("#browseRange").html(inversePct(selected_keys.length, total));
	selected_keys.shift();
	selectSelectedRows();
	displayNumSelected();
	submitSelection(url);
      }
    });
}

/**/
function saveSectionWords(lew, to_lew, sectkey) {
  /*
   * This function handles three instances: saving changes from the section
   * page for a multi section list, saving changes from the list page
   * for a multi section list, and saving changes from the list page for
   * a single section list.
   */
  var m = checkEntryBox(lew.jq_lew);
  if (m) { alert(m); return; }

  // get all the data from the rows
  var datas = lew.getEditorRowData();

  // check to see if there are no vocabs, warn user if so
  if (datas.length==0)
    if (!confirm('There are no words in this section. ' +
		 'Are you sure you want to save this as an empty section?'))
      return;

  // check to see if there are too many, don't let it be saved
  if (datas.length>200) {
    alert("There are too many words in this section.\n\n"
	  + "The maximum allowed is 200"
	  + " and you have entered " + datas.length + ". ");
    return;
  }

  // check for duplicates
  var dict = {};
  var dups = [];
  for (var i = 0, max = datas.length; i < max; i++) {
    var v1 = lew.findChosenOne(datas[i].vocabs);
    if (v1 == null) continue;
    var v2 = lew.findChosenOne(v1.trads);
    var key = v1.key;
    if (v2 != null) key += '|'+v2;
    if (key in dict) dups.push(v1.base);
    dict[key] = v1;
  }
  if (dups.length > 0) {
    if (!confirm('There are duplicates in the list:\n\n' + dups.join(', ') +
		 '\n\nContinue?'))
      return;
  }


  // make the table show that it's saving changes
  $('.screen',lew.jqobj).remove();
  $('.rows_wrapper',lew.jqobj).append(
    $('<div></div>')
      .addClass('screen'))
    .append($('<p><span>Saving...</span></p>').addClass('saving_msg'));

  // take the list of vocabs and send it to the server with the section key
  var params = {rows:$.toJSON(datas), sectkey:sectkey};
  $.retried_post('/vocab/list/save_section', params, function(resp)
  {
    if (resp=='error') resp = { msg:"Server error.", status:'error' };
    else resp = $.evalJSON(resp);
    if (resp.status=='success') {
      // make a new bundle of data, assign it to the table, switch to viewer
      if (top.location.href.indexOf('/list?')>-1) {
	top.location.href = top.location.href;
	return;
      }
      to_lew.rows = datas;
      to_lew.changeToViewer();
      $('#lew_errors').hide();
      $('.root_popup').data('j_obj').close();
      setStudySectionStatus();
      return;
    }

    $('#lew_errors').text("Changes could not be saved: "+resp.msg).show();
    $('.root_popup').data('j_obj').close();
  });

}

function checkEntryBox(lew) {
  var textareas = $('textarea.row_edit', lew);
  for (var i = 0; i < textareas.length; i++) {
    if ($(textareas[i]).val().length > 0) {
      var m = "You still have text in a word entry box. ";
      m += "Press enter after typing in a word to add it to your list.";
      return m;
    }
  }
}

var llew;
function checkIfEditing(e) {
  if (no_exit_warning) return;
  var lew = $('#lew_popup .lew');
  if (lew.length==0) return;

  llew = lew;
  var m = checkEntryBox(lew);
  if (m) return m;

  lew = lew.data('j_obj');
  var same = lew.backup_rows == $.toJSON(lew.getEditorRowData());
  if (!same)
    return "You have not saved any changes made to this section.";
}



/*
 * SECTION EDITOR
 *
 * Here's how section data is structured so that it can easily be passed
 * between javascript and python
 *
 * Section Format:
 *
 * {
 *   'name': string, the name of the section
 *
 *   'key': string, the key of the already existing section
 *
 *   'num_words': how many words are currently in the section. 0 if new
 *
 *   'index': integer, what index it is currently in the list.
 *      null if not yet added
 * }
 *
 * Sections are passed around as Python lists/Javascript Arrays in the order
 * they are in the list.
 *
 */


function makeSectionEditorWidget(sect_data, hide_num_words) {
  var sects = $('<tbody></tbody>');
  for (var i=0; i<sect_data.length; i++) {
    var sect = sect_data[i];
    sects.append(makeSectionEditorRow(sect, hide_num_words));
    //sects.append('<tr><td colspan=3>test</td></tr>');
  }
  sects.sortable({ distance: 15, handle: '.grabber' });
  return $('<div></div>')
    .addClass('section_table_wrapper')
    .append($('<table></table>')
      .addClass('sect_editor')
      .addClass('stdtable')
	.append($('<tbody></tbody>')
	  .append(makeHeaderRow(hide_num_words))
	  .append(sects)));
  return $('<div></div>')
    .addClass('section_table_wrapper')
    .append($('<table></table>')
      .append(sects.prepend(makeHeaderRow(hide_num_words)))
      .addClass('sect_editor').addClass('stdtable'));
}

function makeHeaderRow() {
  return $('<tr></tr>')
    .append($('<th colspan=3></th>')
      .append($('<div></div>')
	.attr('id','add_sect_button')
	.addClass('canvas_button')
	.addClass('blue')
	.html('Add section')
	.click(addNewRow)));
}

function emptySection() {
  return {name:'', num_words:0, key:'', index:null};
}

var sect_index = 0;

function makeSectionEditorRow(sect) {
  var sect_id = 'sect_row_'+sect_index;
  sect_index += 1;

  if (!sect) sect = emptySection();
  return  $('<tr></tr>')
    .addClass('section')
    .data('data',sect)
    .append($('<td></td>')
      .addClass('name_cell')
      .append($('<div></div>')
	.addClass('grabber_wrapper')
	.append($('<img src="/images/vocab/grabber.png" />')
	  .addClass('grabber')))
      .append($('<div></div>')
	.addClass('sect_name_wrapper')
	.append($('<input></input>')
	  .attr('type','text')
	  .attr('tabindex',1)
	  .attr('id',sect_id)
	  .keydown(textAreaKeyDown)
	  .val(sect.name))
	.append($('<label></label>')
	  .attr('for',sect_id)
	  .text('Type section name here'))))
    .append($('<td></td>')
      .addClass('num_words_cell')
      .text(sect.num_words+' words'))
    .append($('<td></td>')
      .addClass('remove_wrapper')
      .addClass('clickable')
      .click(removeSectionRow)
      .append($('<div></div>')
	.addClass('remove_button')));
}

function getSectionParent(row_elem) {
  var elem = $(row_elem)[0];
  return $(findParent(elem, function(e) { return $(e).hasClass('section'); }));
}

function textAreaKeyDown(e) {
  var sect = getSectionParent(e.target);
  var kc=e.keyCode;

  // enter
  if (kc==13) {
    if (tooManySections()) return;
    var to_sect = makeSectionEditorRow();
    sect.after(to_sect);
    $('input',to_sect).focus();
    $('label',to_sect).inFieldLabels();
  }
}

function addNewRow() {
  if (tooManySections(true)) return;
  var new_row = makeSectionEditorRow();
  $('.sect_editor tbody.ui-sortable').append(new_row);
  $('label',new_row).inFieldLabels();
  new_row.focus();
}

function numSections() { return $('.sect_editor tr.section').length; }

function tooManySections(show_alert) {
  if (numSections()>=100) {
    if (show_alert)
      alert("You cannot have more than 100 sections in a list.");
    return true;
  }
  return false;
}


function getSectionData() {
  var rows = $('.sect_editor tr.section');
  var datas = [];
  $.each(rows, function()
  {
    var row = $(this);
    datas.push({name:$.trim($('input',row).val()),
		num_words:row.data('data').num_words,
		key:row.data('data').key});
  });
  return datas;
}


var removed_sections = [];

function removeSectionRow(e) {
  var row = getSectionParent(e.target);
  if (row) {
    var data = row.data('data');
    if (data.key!='') removed_sections.push(data.name);
    row.remove();
  }
}


function editSections() {

  var popup = new Popup().open().clearBody();
  popup.jqobj
    .append($('<h3>Edit Sections</h3>'))

    .append(makeSectionEditorWidget(sect_data))

    .append($('<div></div>')
      .addClass('editor_buttons')
      .append($('<div></div>')
	.addClass('canvas_button')
	.addClass('blue')
	.addClass('medium')
	.attr('id','save_button')
	.text('Save Changes')
	.click(saveSectionChanges))
      .append($('<div></div>')
	.addClass('canvas_button')
	.addClass('red')
	.addClass('medium')
	.attr('id','cancel_button')
	.text('Cancel')
	.click(cancelSectionChanges))
      .append($('<div></div>').addClass('clear')));

  $('label',popup.jqobj).inFieldLabels();
  $('.canvas_button', popup.jqobj).each(function() {
    makeCanvasButton($(this));
    if ($(this).attr('id')=='save_button') $('input', this).attr('tabindex',3);
    if ($(this).attr('id')=='cancel_button') $('input', this).attr('tabindex',2);
    if ($(this).attr('id')=='add_sect_button')
      $('input', this).attr('tabindex',1);
  });

  removed_sections = [];
  if ($('.section').length==0) { addNewRow(); addNewRow(); addNewRow(); }

  popup.lock();

}


function sectionDataValid(sect_data) {
  // If there's a nameless, wordless section at the end, remove it.
  // If it's the only section, don't do this. Let the next handler handle it.
  while (sect_data.length) {
    var last = sect_data[sect_data.length-1];
    if (sect_data.length > 1 && last.name=='' && last.num_words == 0) {
      sect_data.pop();
    }
    else break;
  }

  // don't allow more than 500 sections
  if (sect_data.length>500) {
    alert('No more than 500 sections per list.');
    return false;
  }

  // see if any of the section names are empty or too big, don't allow it
  for (var i=0; i<sect_data.length; i++) {
    var name = $.trim(sect_data[i].name);
    if (name=='') {
      alert('Please fill in a section name for all sections.');
      return false;
    }
    if (name.length > 500) {
      alert('Section names may not be longer than 500 characters each.');
      return false;
    }
  }

  // check to see if any sections have been removed
  // make a warning if so
  var rs_len = removed_sections.length;
  if (rs_len > 0) {
    var rs_names = removed_sections.join(', ');
    if (!confirm("Sections have been removed:\n\n" + rs_names
		 + "\n\nAre you sure you want to remove them?"))
      return false;
  }

  return true;
}


function saveSectionChanges() {
  var new_data = getSectionData();
  if (!sectionDataValid(new_data)) return;
  no_exit_warning = true;
  // submit data via form
  $('#sect_data_input').val($.toJSON(new_data));
  $('#section_edit_form').submit();
}

function cancelSectionChanges() {
  $('.popup').data('j_obj').close();

  /*
  $('#sections_viewer_wrapper').show();
  $('#sect_editor_container').html('');
  $('#edit_div').hide();
  $('.add_words_wrapper').show();
   */
}

var no_exit_warning = false;

function checkIfSectionEditing(e) {
  debug.info(no_exit_warning);
  if (no_exit_warning) return;
  var sect_editor = $('.sect_editor');
  if (sect_editor.length>0) {
    $(window).bind('beforeunload', checkIfSectionEditing);
    return "You have not saved any changes made to the sections.";
  }
}


function uncollapseSections() {
  $('#collapsed_row').remove();
  $('#addsectiontable tr').show();
}


function setStudySectionStatus() {
  // study button only enabled when there are enough words to study
  if ($('tr.row').length >= 4) {
    $('#enabled_note').removeClass('hidden');
    $('#disabled_note').addClass('hidden');
    $('#section_footer .canvas_button')
      .removeClass('disabled')
      .unbind();
  }
  else {
    $('#enabled_note').addClass('hidden');
    $('#disabled_note').removeClass('hidden');
    $('#section_footer .canvas_button')
      .addClass('disabled')
      .bind('click',function() { return false; });
  }
}



/* NEW LIST PAGE */

function openSingleSectWordLEW() {
  editSectionWords(null, 0);
}

function editSectionWords(elem, sect) {
  var args = {list:listviewing,sect:sect,make_sect:true};
  var p = new Popup('/vocab/listsect/edit_popup', args);
  if (elem) {
    debug.info(elem);
    debug.info($(elem).offset().top);
    p.positionFromTop($(elem).offset().top);
    debug.info('done');
  }
  p.open().lock();
}


var LEW_onloadCallback = function() {
  var num_prog = (lang=='ja') ? 3 : 4;

  var note_row = $('<tr></tr>').addClass('hidden');
  note_row.append($('<td colspan='+(num_prog+3)+'></td>')
    .append($('<div></div>').addClass('notification_div')));
  $('tbody',this.jq_lew).prepend(note_row);

  var header_row = $('<tr></tr>');

  header_row
    .append($('<th></th>')
      .append($('<input type="checkbox" />')))
    .append($('<th></th>')
      .addClass('word_col')
      .append($('<span>Selected: </span>').addClass('selected_label'))
      .append($('<span class="num_selected_num">0</span>'))
      .append($('<span>Remove From My Words</span>')
	.addClass('canvas_button')
	.addClass('small')
	.addClass('red')
	.addClass('disabled')
	.addClass('lew_remove_button')
	.click(this.deleteSelected)))
    .append($('<th colspan='+(num_prog)+'></th>').addClass('progress_col')
      .append($('<span>Progress</span>'))
      .append($('<span class="simp_progress">'
		+ '(<span class="clickable info_bubble_button">'
		+ 'more...</span>)</span>'))
      .append($('<span class="more_progress">'
		+ '(<span class="clickable">less...</span>)</span>')));

  // checkboxes
  $('tbody',this.jq_lew).prepend(header_row);

  this.updateRemoveButton = function(js_lew) {
    return function() {
      var remove_button = $('.lew_remove_button', js_lew.jq_lew);
      if ($('td input[type="checkbox"]:checked', js_lew.jq_lew).length > 0)
	remove_button.removeClass('disabled');
      else remove_button.addClass('disabled');
    };
  }(this);

  $('th input[type="checkbox"]', this.jq_lew)
    .click(this.toggleSelectAll)
    .click(updateAllCheckbox)
    .click(this.updateRemoveButton);
  $('td input[type="checkbox"]', this.jq_lew)
    .click(updateAllCheckbox)
    .click(this.updateRemoveButton);

  // progress switcher
  debug.info('progess_switcher');
  $('.simp_progress .clickable',this.jq_lew).click(
    function(js_lew) {
      return function() { js_lew.setProgMode('more', true); }; }(this));

  $('.more_progress .clickable',this.jq_lew).click(
    function(js_lew) {
      return function() { js_lew.setProgMode('simp', true); }; }(this));

  // canvas buttons
  $('.canvas_button').each(function() { makeCanvasButton($(this)); });
};


function addSingleSectionPopup() {
  var args = {list:listviewing};
  var popup = new Popup('/vocab/list/add_single_section_popup', args);
  popup.open();
}
