/* setup admin pages */

(function() {
  'use strict';

  var ambiguous_date_regex = new RegExp(
        '(^|\\D)((\\d{1,2})/(\\d{1,2})/(\\d{2})?(\\d{2}))($|\\D)');

  function show_message(message, message_area) {
    var message_node;

    if (!message_area) {
      message_area = document.getElementById('messages');
    }

    message_area.innerHTML = '';

    if (message) {
      message_node = document.createTextNode(message);
      message_area.appendChild(message_node);

      message_area.parentNode.classList.remove('hidden');
    }
  }

  function post_form(form, button, onsuccess, message_area) {
    var request, data;

    // clear previous messages
    show_message(null, message_area);

    request = new window.XMLHttpRequest();
    request.open('POST', form.action, true);
    data = new window.FormData(form);

    if (button) {
      // disable submit button until the request loads or fails (to prevent
      // multiple identical sumissions in a row)
      button.disabled = true;
    }

    // set up events for load and error
    request.onload = function() {
      button.disabled = false;
      if (request.status >= 200 && request.status < 400) {
        data = JSON.parse(request.responseText);
        if (data.success) {
          onsuccess(data);
        }
        else {
          show_message(data.error, message_area);
        }
      }
      else {
        show_message('Error communicating with server, got status '+request.status, message_area);
      }
    };
    request.onerror = function () {
      button.disabled = false;
      show_message('Error communicating with server', message_area);
    };

    // post data
    request.send(data);
  }

  function setup_replace_entries() {
    var form, button;

    form = document.getElementById('replace_entries_form');
    // do nothing if this isn't the replace_entries page
    if (!form) { return; }
    form.addEventListener('submit', form_submit_handler);

    button = document.getElementById('submit_button');
    button.addEventListener('click', function() {
      post_form(form, button, function() {
        show_message('Entries replaced successfully');
      });
    });
  }

  function check_source_date(value) {
    var match, a, b, month, day, yyyy, yy, mm, dd, detected_format;

    // clear message area
    show_message(null);

    if (!value) { return true; }

    match = ambiguous_date_regex.exec(value);
    if (!match) { return true; }

    a = parseInt(match[3]);
    detected_format = match[3].length == 1 ? 'A/' : 'AA/';

    b = parseInt(match[4]);
    detected_format += match[4].length == 1 ? 'B/' : 'BB/';

    // try to guess whether first number is month or day
    // default to month first
    if (a > 12 && b <= 12) {
      // day first
      day = a; month = b;
      detected_format = detected_format.replace(/A/g, 'D').replace(/B/g, 'M');
    }
    else {
      // month first
      month = a; day = b;
      detected_format = detected_format.replace(/A/g, 'M').replace(/B/g, 'D');
    }

    // zero pad if necessary
    mm = month < 10 ? '0'+month : month;
    dd = day < 10 ? '0'+day : day;

    yy = match[6];
    // expand to 4 digits
    yyyy = match[5] ? match[5]+yy : parseInt(yy)+2000;
    detected_format += match[5] ? 'YYYY' : 'YY';

    show_message(
      'The source seems to contain an ambiguous date.\nPlease replace '+
      'it with an ISO-8601 YYYY-MM-DD\nor a Korean YYMMDD formatted '+
      'date.\n\nDate found: '+match[2]+' (interpreting as '+detected_format+')'+
      '\nPossible replacements: '+yyyy+'-'+mm+'-'+dd+' or '+yy+mm+dd
    );

    return false;
  }

  function setup_add_entries() {
    var form, button, source_text_input;

    form = document.getElementById('add_entries_form');
    // do nothing if this isn't the add_entries page
    if (!form) { return; }
    form.addEventListener('submit', form_submit_handler);

    button = document.getElementById('submit_button');
    source_text_input = form.querySelector('input[name="source_text"');

    // in case we're reloading
    button.disabled = false;
    show_message(null);

    button.addEventListener('click', function() {
      if (!check_source_date(source_text_input.value)) { return; }

      post_form(form, button, function(data) {
        show_message("Post successful.\nPlease wait while you're redirected.");

        // disable button while we wait
        button.disabled = true;

        // on successful post, redirect to the admin page for fine tuning
        window.setTimeout(function () {
          window.location.href = data.admin_url;
        }, 1000);
      });
    });

    source_text_input.addEventListener('change', function() {
      check_source_date(source_text_input.value);
    });
  }

  function cleanup_add_page() {
    // do nothing if this isn't the add_entries page
    if (!document.getElementById('add_entries_form')) { return; }

    document.getElementById('submit_button').disabled = false;
    show_message(null);
  }

  function toggle_checkboxes(checked) {
    var found, i, checkbox;

    found = document.getElementsByClassName('video_checkbox');
    for (i=0; i<found.length; i++) {
      checkbox = found[i];
      checkbox.checked = checked;
    }
  }

  function count_words(string) {
    var i, count, array;
    array = string.value.split(' ');
    count = 0;
    for (i=0; i<array.length; i++) {
      if (array[i]) {
        count++;
      }
    }
    return count;
  }

  function update_submit_button() {
    var videos, action, submit, new_names, tags;

    videos = document.getElementById('videos');
    action = document.getElementById('select_action');
    submit = document.getElementById('submit_button');
    new_names = document.getElementById('new_names');
    tags = document.getElementById('tags');

    // enable only if videos and an action have been selected
    submit.disabled = true;
    if (videos.value && action.value) {
      if (action.value === 'rename_videos') {
        // in the case of rename_videos, check length for videos and new_names
        if (count_words(videos) === count_words(new_names)) {
          submit.disabled = false;
        }
      }
      else if (action.value === 'add_tags' || action.value === 'remove_tags') {
        if (tags.value) {
          submit.disabled = false;
        }
      }
      else {
        submit.disabled = false;
      }
    }
  }

  function show_inputs(action) {
    var source, source_url, source_text, tags, new_names;

    source_url = document.getElementById('source_url');
    source_text = document.getElementById('source_text');
    tags = document.getElementById('tags');
    new_names = document.getElementById('new_names');

    // hide and clear all at first
    source_url.classList.add('hidden');
    source_url.value = '';

    source_text.classList.add('hidden');
    source_text.value = '';

    tags.classList.add('hidden');
    tags.value = '';

    new_names.classList.add('hidden');
    new_names.value = '';

    if (action === 'change_source') {
      // fill source, if available
      source = get_source();
      if (source) {
        if (source.url) {
          source_url.value = source.url;
        }
        if (source.text) {
          source_text.value = source.text;
        }
      }

      source_url.classList.remove('hidden');
      source_text.classList.remove('hidden');
    }
    else if (action === 'add_tags' || action === 'remove_tags') {
      tags.classList.remove('hidden');
    }
    else if (action === 'rename_videos') {
      new_names.classList.remove('hidden');
    }

    update_submit_button();
  }

  // place a lock to make sure we'll only do this once when all checkboxes are
  // checked or unchecked
  var videos_input_lock = false;

  function wait_and_update_video() {
    if (videos_input_lock) { return; }
    //videos_input_lock = true;
    window.setTimeout(function() {
      update_videos_input();
      videos_input_lock = false;
      update_submit_button();
    }, 100);
  }

  function setup_videos_input_updaters() {
    var found, i, checkbox;

    found = document.getElementsByClassName('video_checkbox');
    for (i=0; i<found.length; i++) {
      checkbox = found[i];
      checkbox.addEventListener('change', wait_and_update_video);
    }
  }

  function update_videos_input() {
    var found, i, checkbox, videos_input;

    videos_input = document.getElementById('videos');
    videos_input.value = '';

    found = document.getElementsByClassName('video_checkbox');
    for (i=0; i<found.length; i++) {
      checkbox = found[i];
      if (checkbox.checked) {
        videos_input.value += ' '+checkbox.name;
      }
    }
  }

  function get_source() {
    /* returns source url and title if and only if all selected videos have the
     * same source, otherwise returns null */
    var found, i, checkbox, num, prev_url, prev_text,
        url, text, url_elem, text_elem;

    prev_url = prev_text = null;

    // check all sources, and return null if any of them differ
    found = document.getElementsByClassName('video_checkbox');
    for (i=0; i<found.length; i++) {
      checkbox = found[i];
      if (checkbox.checked) {
        url = text = null;
        // find source url and text based on the checkbox's number
        num = checkbox.dataset.num;
        url_elem = document.getElementById('url'+num);
        if (url_elem && url_elem.firstChild) {
          url = url_elem.firstChild.nodeValue;
        }
        text_elem = document.getElementById('text'+num);
        if (text_elem && text_elem.firstChild) {
          text = text_elem.firstChild.nodeValue;
        }

        if ((!prev_url) && (!prev_text)) {
          prev_url = url;
          prev_text = text;
        }
        else if (prev_url !== url || prev_text !== text) {
          // sources differ, return null
          return null;
        }
      }
    }

    // only return url and text if at least one source was found
    if (url || text) {
      return {"url": url, "text": text};
    }
    return null;
  }

  function video_button_click_handler(event) {
    /* jshint validthis:true */
    var button, form, message_area, input;

    event.preventDefault();

    button = this;
    form = button.parentNode;
    message_area = document.getElementById('messages_for_'+button.dataset.video);
    input = document.getElementById('tags_for_'+button.dataset.video);

    post_form(form, button, function() {
      show_message('OK', message_area);
      // clean up input
      input.value = '';
    }, message_area);
  }

  function setup_individual_video_forms() {
    /* sets up events for each video's individual form */
    var i, found;

    found = document.getElementsByClassName('submit_video_tags');
    for (i=0; i<found.length; i++) {
      found[i].addEventListener('click', video_button_click_handler);
      found[i].parentNode.addEventListener('submit', form_submit_handler);
    }
  }

  function form_submit_handler(event) {
    event.preventDefault();
    return false;
  }

  function setup_admin_page() {
    var form, button, check_all, select, new_names, tags, i, found;

    form = document.getElementById('admin_page_form');
    // do nothing if this isn't the add_entries page
    if (!form) { return; }
    form.addEventListener('submit', form_submit_handler);

    button = document.getElementById('submit_button');
    button.addEventListener('click', function() {
      var source_text = document.getElementById('source_text'),
        select_action = document.getElementById('select_action');

      if (select_action.value == 'change_source') {
        // check source text before submitting
        if (!check_source_date(source_text.value)) { return; }
      }

      post_form(form, button, function() {
        show_message("Post successful.\nPlease reload the page to see the changes.");

        // clear up inputs
        select_action.value = '';
        show_inputs('');
        document.getElementById('videos').value = '';
        document.getElementById('check_all').checked = false;
        found = document.getElementsByClassName('video_checkbox');
        for (i=0; i<found.length; i++) {
          found[i].checked = false;
        }
      });
    });

    setup_individual_video_forms();

    check_all = document.getElementById('check_all');
    check_all.addEventListener('change', function() {
      toggle_checkboxes(this.checked);
      wait_and_update_video();
    });

    select = document.getElementById('select_action');
    select.addEventListener('change', function() {
      show_inputs(this.value);
    });
    show_inputs(select.value);

    setup_videos_input_updaters();

    tags = document.getElementById('tags');
    tags.addEventListener('input', update_submit_button);

    new_names = document.getElementById('new_names');
    new_names.addEventListener('input', update_submit_button);
  }

  function setup() {
    setup_replace_entries();
    setup_add_entries();
    setup_admin_page();
  }

  function cleanup() {
    cleanup_add_page();
  }

  document.addEventListener('DOMContentLoaded', setup);
  window.addEventListener('beforeunload', cleanup);

}());
