var groups_displayed = 0;

(function($){

  var groups,
      templates,
      summary,
      feedbackForm,
      noMatches,
      contentHider,
      sentenceCount = 0,
      baseUrl = location.protocol + "//" + location.host,
      api_key = 'api_key=r9kw6yuppsyfqh2fs69tbgrg',
      extractCall = Smartfm.API.server + 'extract/words?text=',
      wordCall = Smartfm.API.server + 'words/',
      textCall = Smartfm.API.server + 'words?keyword=',
      history = [],
      e = $.createElement,
      auto_click = true,
      lookup_word = '',
      searchCount = 0,
      minItemsForStudy = 6,
      itemsPerSession = 0;


  $(document).ready(function() {

    $('.dictionary').itemActions(); // Initialize item actions like add to collected/etc...

    $('#search_keyword').focus();

    historyList();
    $('.word_history').append('<a id="clear_history" href="#clear_history" alt="' + $.globalize('Clear History') + '">' + $.globalize('Clear History') + '</a>');

    $('a#clear_history').bind('click', function () {
      history = [];
      historyUpdate();

      return false;
    });


    $('#study_history').click(function(){
      if( $('#history_goals ul').is(':visible') ) {
        hideHistoryStudy();
      }
      else {
        showHistoryStudy();
      }
      return(false);
    });

    $('.definition_link').live('click', function(e){
      $(this).siblings('.actions').find('.header').click();
      e.stopImmediatePropagation();
      return(false);
    });
    
    $('.sentence_link').live('click', function(e){
      $(this).closest('.sentence').find('.header').click();
      e.stopImmediatePropagation();
      return(false);
    });

    // Templates
    groups = $('#groups');
    summary = $('#summary');
    noMatches = $('#no_matches');
    feedbackForm = $('#feedback_form form');
    templates = {
      group: $('#templates .group'),
      attribution: $('#templates .attribution'),
      sentence: $('#templates .sentence'),
      feedback: $('#templates .feedback'),
      feedbackForm: $('#templates .feedback_form'),
      contentHider: $('#templates .content_hider')
    };

    $('.feedback_flag').live('click', function(){ return(false) });

    // Render page
    if (search_type == 'word') {
      auto_click = false;
      lookup_word = $('#search_keyword').val();
      displayWords(keyword_groups);
    }
    else if (search_type == 'text') {
      parseSentences();
    }

    // Initialize bookmarklet
    $('#bookmarklet').attr('href',
      "javascript:void(function(){var%20d=document,w=window,u=(window.getSelection)?" + 
      "w.getSelection():d.selection.createRange(),t=(u.text)?u.text+'':u+'';var%20wr=window.open('" + 
      location.protocol + "//" + location.host + "/jisho/?keyword='+encodeURIComponent(t),'');}());"
    );

    // Set up content hiding
    $('#toggle_hiding').click(function(){
      $('.dictionary').toggleClass('hiding');
      $('.hiding .hidable').each(function(){
        var hider = templates.contentHider.clone();
        if($(this).hasClass('hidden_content')) {
          $('a', hider).text('Show this');
        }
        $(this).prepend(hider);
      });
        
      $('#groups .content_hider a').click(function(){
        hidable = $($(this).parents('.hidable')[0]);
        $.ajax({url: location.protocol + "//" + location.host + '/dictionary/flag',
          type: 'POST',
          data: {type: hidable.data('object_type'), id: hidable.data('object_id')},
          context: hidable,
          complete: function(xhr){
            if(xhr.status == 201) {
              $(this.context).addClass('hidden_content');
              $('> .content_hider a', this.context).text('Show this');
            }
            else {
              $(this.context).removeClass('hidden_content');
              $('> .content_hider a', this.context).text('Hide this');
            }
          }
        });
        return(false);
      });
      
      return(false);
    });
    
    // Set form behavior
    $('.search form').submit(function(){
      var text = $('form .keyword').val();
      if (text.split(' ').length > 2) {
        $(this).attr('method', 'post');
        return(true);
      }
      else {
        window.location = location.protocol + '//' + location.host + '/jisho/' + encodeURIComponent(text);
      }
      return(false);
    });

    // Focus form
    $('form .keyword').select();
  });


  var loadToolTips = function () {
    $('div.definitions ul li a').each(function () {
      $(this).qtip({
        content: '<a href="/jisho/' + $(this).html().split(', ')[0] + '" data-track-click="dictionary/tooltip/search_item">' + $.globalize('Search') + '</a> | <a href="' + $(this).attr('href') + '" data-track-click="dictionary/tooltip/goto_item">' + $.globalize('Go to item') + '</a>',
        show: {
          when: 'click',
          solo: true,
          delay: 0,
          effect: { length: 0 }
        },
        style: {
          width: 190,
          name: 'cream',
          tip: 'bottomLeft',
          'font-size': '14px'
        },
        position: { corner: { tooltip: 'bottomLeft', target: 'topMiddle' } },
        hide: 'unfocus',
        api: {
          beforeRender: function () {
          }
        }
      }).click(function () {
        return false;
      });
    });

    $('li.sentence div.text p>a').each(function () {
      $(this).qtip({
        content: '<a href="/jisho/?keyword=' + encodeURIComponent($(this).text()) + '" data-track-click="dictionary/tooltip/search_sentence">' + $.globalize('Search sentence') + '</a> | <a href="' + $(this).attr('href') + '" data-track-click="dictionary/tooltip/goto_sentence">' + $.globalize('Go to sentence') + '</a>',
        show: {
          when: 'click',
          solo: true,
          delay: 0,
          effect: { length: 0 }
        },
        style: {
          width: 220,
          name: 'cream',
          tip: 'bottomLeft',
          'font-size': '14px'
        },
        position: { corner: { tooltip: 'bottomLeft', target: 'topMiddle' } },
        hide: 'unfocus',
        api: {
          beforeRender: function () {
          }
        }
      }).click(function () {
        return false;
      });
    });
  };

  // Text search
  var parseSentences = function() {
    $('#text ul li').each(function () {

      var sentence = $(this).children('.original').html(),
          sentence_attribution = templates.attribution.clone(),
          sentence_id = 'sentence_' + sentenceCount++;

      $(this).attr({'id': sentence_id, 'class': 'sentence'});
      $(this).children('.original').attr('class', 'text');
      $(sentence_attribution).html($.globalize('Translation by Google'));
      $(this).children('.translation').html(sentence_attribution);

      googleTranslate(sentence, sentence_id)
      findText(sentence, sentence_id);
    });

  };

  var googleTranslate = function (sentence, sentence_id) {
    var language = 'en',
        translation_language = 'ja';

    $.getJSON('http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=' +
      encodeURIComponent(sentence) + '&langpair=' + language +'%7C' +
      translation_language + '&callback=?', function (result) {

      $('#' + sentence_id).children('.translation').prepend(result.responseData.translatedText);
    });
  };

  var findText = function (sentence, sentence_id) {
    var language = 'en',
        translation_language = 'ja';

    $.getJSON(extractCall + encodeURIComponent(sentence) + '&' + api_key + '&words_only=true&language=' +
      language + '&translation_language=' + translation_language + '&callback=?', function(data) {

      addCustomHTML(data, language, sentence_id);
    });
  };

  addCustomHTML = function (wordList, language, sentence_id) {
    keys = pageWordsRegEx(wordList, language);

    if (keys.length < 1) return false;

    var aposStr = decodeURI("%E2%80%99"),
      fixApos = new RegExp(aposStr,"gm"),
      keysStr = "(" + keys + ")",
      findKeysStr = new RegExp(keysStr,"g");

    var text = $('#' + sentence_id).children('.text').html(),
        newText = '',
        text_LC = text.toLowerCase().replace(fixApos, "'"),
        lastMatch = 0;

    while (match = findKeysStr.exec(text_LC)) {
      if (wordList[match[0]]) {
        newText += text.substr(lastMatch, (match.index - lastMatch)) +
          '<a class="item" href="#' + text.substr(match.index, match[0].length) + '" data-track-click="dictionary/sentence/match_click">' +
          text.substr(match.index, match[0].length) + '</a>';
        lastMatch = match.index + match[0].length;
        match.lastIndex = 0;
      }

      $('#' + sentence_id).children('.text').html(newText + text.substr(lastMatch, text.length - lastMatch));
    }

    $('a.item').click(function(){
      $('a.current_item').removeClass('current_item');
      $(this).addClass('current_item');
      var url = wordCall + encodeURIComponent($(this).text());
      lookup_word = $(this).text();
      $.getJSON(url + '?callback=?', {}, function(data){
        displayWords(data);
      });
      return false;
    });

    if (sentence_id == 'sentence_0') {
      $('#' + sentence_id + ' a.item:first').click();
    }
  };

  var pageWordsRegEx = function (wordList, language) {
    if (language != 'ja') return "[a-z'-]{3,}";

    var keys = [];

    for (key in wordList) keys.push(key);

    return keys.sort(this.sortByLength).join("|");
  };

  // Word search
  var displayWords = function(keyword_groups) {
    groups.empty();
    var items_for_pos = {};
    noMatches.hide();
    groups_displayed = 0;

    // Setup the groups
    $.each(keyword_groups, function(group_i){
      // Keyword level
      var previous_keyword = null;
      $.each(this, function(pos_i){
        // Part of speech group level
        var new_group = templates.group.clone();
        var definitions = $('.definitions ul', new_group);
        var sentences = $('.sentences ul', new_group);
        var identifier = 'g' + group_i + 'w' + pos_i;
        var pos = this['part_of_speech'];
        var sounds = e('ul', {'class': 'sounds'});
        groups_displayed++;
        
        if (!this['transcription']) {
          transcription = '';
        }
        else
        {
          transcription = e('span', {text: '/' + this['transcription'] + '/', 'class': 'transcription'});
        }

        $('h2', new_group).append(e('a', {name: identifier})).
                           append(e('span', {'class': 'headword clearfix'}).
                           append(this['keyword']).
                           append(transcription).
                           append(e('span', {text: $.globalize(this['part_of_speech']), 'class': 'pos'}))).
                           append(sounds);

        if (items_for_pos[pos] == undefined) {
          items_for_pos[pos] = [];
        }
          
        // Hidden group
        if( this.hidden ) {
          new_group.addClass('hidden_content');
        }
        else {
          items_for_pos[pos].push({'response': this, 'identifier': identifier});
        }

        // Related words
        var synonyms = [];
        if( this.synonyms ) {
          $.each(this.synonyms, function(i, text){
            synonyms.push(text);
          });
        }
        if( this.see_also ) {
          $.each(this.see_also, function(i, text){
            synonyms.push(text);
          });
        }
        max = synonyms.length;
        $.each(synonyms, function(i, text){
          $('.synonyms', new_group).append(e('a', {href: '/jisho/' + encodeURIComponent(text), text: text})).append(max == i+1 ? '' : ', ');
          $('.synonyms', new_group).removeClass('hidden').parent().removeClass('hidden');
        });
        if( this.antonyms ) {
          max = this.antonyms.length;
          $.each(this.antonyms, function(i, text){
            $('.antonyms', new_group).append(e('a', {href: '/jisho/' + encodeURIComponent(text), text: text})).append(max == i+1 ? '' : ', ');
            $('.antonyms', new_group).removeClass('hidden').parent().removeClass('hidden');
          });
        }

        $.each(this.items, function(i){
          // Item level
          var new_definition = e('li', {'class': 'hidable definition item'}).data('object_type', 'definition').data('object_id', this.id).data('item', this);

          // For hiding the group. It's identified by any of its constituent items
          new_group.data('object_type', 'group');
          new_group.data('object_id', this.id);
          
          // Hidden definition
          if( this.hidden ) {
            new_definition.addClass('hidden_content');
          }

          var endpoint_link = e('a', {href: 'http://smart.fm/items/' + this.id, text: this.response, 'class': 'definition_link'});
          var dropdown = $($.smartfm.templates.itemActions(this, {text: this.response, from_jisho: true})).dropdown();
          var actions = e('div', {'class':'actions'}).append(dropdown);
          var actions_hover_area = e('div', { 'class': 'actions_hover_area clearfix'}).append(actions).append(endpoint_link);
          actions_hover_area.css('z-index', 100 - i);
          new_definition.append(actions_hover_area);
          definitions.append(new_definition);
        });

        $.each(this.sounds, function(i){
          var new_sound = e('li', {'class': 'hidable_off'});

          // Hidden sound
          if( this.hidden ) {
            new_sound.addClass('hidden_content');
          }
          
          sounds.append(new_sound.
                 append(e('a', {'class': 'sound ' + (this.human ? 'sound_human' : ''), rel: 'audio', href: this.url})));
        });
        $('li', sounds).data('object_type', 'item-audio').data('object_id', this.id);

        $.each(this.sentences, function(i){
          // Sentence level
          var new_sentence = templates.sentence.clone();
          var actions = $.smartfm.templates.sentenceActions(this);
          new_sentence.data('object_type', 'sentence').data('object_id', this.id);
          
          $('.text p', new_sentence).prepend(e('a', {href: 'http://smart.fm/sentences/' + this.id,
                                                     html: this.text,
                                                     'class': 'sentence_link'}));
          $('.translation p', new_sentence).html(this.translation);
          $('.actions_and_image', new_sentence).append(e('div', {'class': 'actions'}).append($(actions).dropdown()));

          if (typeof(this.sound) == 'string') {
            $('.sounds', new_sentence).html(e('a', {'class': 'sound', rel: 'audio', href: this.sound}));
          }
          else if (typeof(this.sound) == 'object' && this.sound != null && this.sound.hasOwnProperty('url')) {
            $('.sounds', new_sentence).html(e('a', {'class': 'sound ' + (this.sound.human ? 'sound_human' : ''), rel: 'audio', href: this.sound.url}));
            $('.sounds', new_sentence).data('object_type', 'sentence-audio').data('object_id', this.id);
            
            // Hidden sound
            if( this.sound.hidden ) {
              $('.sounds', new_sentence).addClass('hidden_content');
            }
          }

          if (this.image && this.image.icon) {
            $('.image', new_sentence).html(e('a', {href: this.image.original,
                                                   'class': 'modal_jisho' + searchCount + ' clearfix show_fancy_title',
                                                   rel: 'large_image',
                                                   title: '<div class="dictionary"><div class="sentence">' +
                                                          '<div class="text">' + $('div.text', new_sentence).html() + '</div>' +
                                                          '<div class="translation">' + $('.translation', new_sentence).html() + '</div>' +
                                                          '</div></div>'}).
                                           append(e('img', {src: this.image.icon, 'class': 'icon_image'})).
                                           append(e('img', {src: '/html5/images/magnifying_glass_icon.png', 'class': 'magnifier hidden'})));
            $('.image', new_sentence).data('object_type', 'sentence-image').data('object_id', this.id);
            // Hidden image
            if( this.hidden ) {
              $('.image', new_sentence).addClass('hidden_content');
            }
          }

          // Hidden sentence
          if( this.hidden ) {
            new_sentence.addClass('hidden_content');
          }

          sentences.append($(new_sentence).wrap('<li><li/>'));
        });

        addFlag($('.definitions', new_group), 'items', {word: this['keyword'], pos: this['part_of_speech']});
        addFlag($('.sentences', new_group), 'sentences', {word: this['keyword'], pos: this['part_of_speech']});

        groups.append(new_group);
        previous_keyword = this['keyword'];
      });
    });

    $('#groups .group .meta').each(function(){
      var things = $('.foldable > li:gt(2)', this);

      // Hide everything but the top three of every content type
      if (things.length > 0) {
        things.hide();
        things.parents('.meta').
               append(e('a', {href: "#", 'class': "show_all", text: $.globalize('Show all')}).
               click(function(){
          things.toggle();
          if (things.is(':visible')) {
            $(this).text($.globalize('Show less'));
          }
          else
          {
            $(this).text($.globalize('Show all'));
          }
          return(false);
        }));
      }

      // Hide content groups that has no content
      if ($('.foldable li', this).length == 0) {
        $(this).hide();
      }
    });

    if (search_type == 'word' && groups_displayed > 2)
      displaySummary(items_for_pos);

    if (groups_displayed == 0) {
      noMatches.show();
      summary.hide();
    } else if (!auto_click) {
      historyAdd(lookup_word.toLowerCase());
    } else if (auto_click) {
      auto_click = false;
    }

    $('.feedback div').dropdown({
      autoZIndexDescendingFrom: 50
    });

    $('.modal_jisho' + searchCount).fancybox({centerOnScroll: false});
    searchCount = searchCount + 1;
  };

  var addFlag = function(element, type, context){
    var new_feedback = templates.feedback.clone();
    var ul = $('ul', new_feedback);

    if (type == 'sentences') {
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect sentence')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect translation')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect audio')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect image')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect word highlighted')})));
    }
    else if (type == 'items') {
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect word')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect definition')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect part of speech')})));
      ul.append(e('li').append(e('a', {href: '#', text: $.globalize('Incorrect audio')})));
    }

    $('li a', new_feedback).click(function(){
      sendFlag($(this).text() + ' in ' + type + ' when searching for ' + $('#search_keyword').val(), 'Word: ' + context['word'] + ', part of speech: ' + context['pos']);
      return(false);
    });

    if (type == 'sentences') {
      $('h3', element).prepend(new_feedback);
    }
    else if (type == 'items') {
      element.prev('h2').prepend(new_feedback);
    }
  };

  var sendFlag = function(subject, body){
    $('#feedback_subject', feedbackForm).val(subject);
    $('#feedback_body', feedbackForm).val(body);
    feedbackForm.submit();
    $('.feedback').click();
  };

  var displaySummary = function(items_for_pos){
    summary.empty();

    $.each(items_for_pos, function(pos, entries){
      if( entries.length == 0) {
        return;
      }
      
      var pos_group = e('div', {'class': 'pos_group'});
      var keyword_group = e('ol', {'class': 'keyword_group'});
      pos_group.append(e('h3', {'class': 'pos', text: $.globalize(pos)}));

      $.each(entries, function(i, entry){
        responses = [];
        $.each(entry['response']['items'], function(j, item){
          if (j >= 2) return;
          responses.push(item['response']);
        });
        keyword_group.append(e('li', {'class': ''}).
                      append(e('a', {href: '#' + entry['identifier'], text: entry['response']['keyword']})).
                      append(e('span', {'class': 'response', text: responses.join(', ')})));
      });

      pos_group.append(keyword_group);
      summary.append(pos_group);
    });

    // Give them equal width
    var num = $('.pos_group').length;
        num = (100/num - 5);
    $('.pos_group').css('width', num + '%');

    // Hide everything but the top three of every PoS group
    $('#summary ol').each(function(){
      var things = $('li:gt(2)', this);

      if (things.length > 0) {
        things.hide();
        things.parents('#summary').
               append(e('a', {href: "#", 'class': "show_all", text: $.globalize('Show all')}).
               click(function(){
          things.toggle();
          if (things.is(':visible')) {
            $(this).text($.globalize('Show less'));
          }
          else
          {
            $(this).text($.globalize('Show all'));
          }
          return(false);
        }));
      }

    });

    summary.show();
  };

  var historyAdd = function (key) {
    var el = $('.definitions ul li a.definition_link');
    var href = el.attr('href');
    var match = href.match(/\d+$/);
    if(!match) return;
    var item = match[0];

    for (var i in history) {
      word = history[i].split('|');

      if (word[0] == key) history.splice(i, 1);
    }

    if (history.length > 14) history.pop();

    history.unshift(key + '|' + item);
    historyUpdate();
  };

  var historyUpdate = function () {
    var item_count = 0,
        ids = [];

    $('.word_history ol').html('');

    for (var i in history) {
      word = history[i].split('|');

      $('.word_history ol').append(e('li').append(e('a', {href: '/jisho/' + encodeURI(word[0]),
                                                          'data-track-click': 'dictionary/history/click/' + i,
                                                          text: word[0]}))
      );

      if (typeof word[1] != 'undefined') {
        item_count++
        ids.unshift(word[1]);
      }
    }

    if (item_count >= 1) {
      $('#study_history_launcher').show();
      studyHistoryItems = ids.join(',');
      itemsPerSession = item_count;
    }
    else {
      $('#study_history_launcher').hide();
    }

    if (typeof(localStorage) == 'undefined') {
      $.cookie('history', history.join(','));
    } else {
      localStorage.setItem('history', history.join(','));
    }
  };

  var showHistoryStudy = function(){
    $('#study_history').text($.globalize('Loading ...'));
    
    $.ajax({
      url: Smartfm.API.server + 'goals.json',
      dataType: 'jsonp',
      data: {item_ids: studyHistoryItems, per_page: 5},
      success: function(data, text, request){
        $('#history_goals .loading').hide();
        $('#history_goals ul').empty();
        if (data['goals'].length > 0) {
          $.each(data['goals'], function(i){
            $('#history_goals ul').append(e('li')
                                  .append(e('a', {href: '/goals/' + this['id'],
                                                  target: '_blank',
                                                  text: this['title']}).attr('data-track-click','dictionary/history_goal_match/goal')));
          });
        }
        else {
          $('#history_goals ul').append(e('li', {text: $.globalize('No goals found')}));
        }
        
        $('#study_history').hide();
        $('#history_goals h4').show();
      }
    });

    // if (itemsPerSession >= minItemsForStudy) {
    //   $('#items_until_study').hide();
    //   $('#launch_history_study').attr('href', '/study/items?item_ids=' + studyHistoryItems + 
    //     '&autosave=false&special_characters=1&timer_spelling=0.5&content_volume=0.5&ja_study_mode=0&color_scheme=0' + 
    //     '&lang=en&hans_study_mode=0&items_per_session=' + itemsPerSession + '&effects_volume=0.5&timer_mc=0.5&sound_theme=0&started=false' + 
    //     '&hant_study_as_hans=0&milestone_time=3&anonymous=true').show();
    // }
    // else {
    //   $('#launch_history_study').hide();
    //   $('#items_until_study').text($.globalize('Search {number} more items to study your history', {number: minItemsForStudy - itemsPerSession})).show();
    // }
    
    $('#history_goals ul').show();
  };

  var hideHistoryStudy = function(){
    $('#history_goals ul').empty().hide();
  };

  var historyList = function () {
    var h = '';

    if (typeof(localStorage) == 'undefined') {
      h = $.cookie('history');
    } else {
      h = localStorage.getItem('history');
    }

    if (h) {
      history = h.split(',');
      historyUpdate();
    }
  };

})(jQuery);

