(function() {
  var signalGuess, skipBtnTimerRunning;

  String.prototype.startsWith = function(s) {
    return this.lastIndexOf(s, 0) === 0;
  };

  window.FlashCard = Backbone.Model.extend({
    defaults: {
      kana: '',
      romaji: [],
      charset: 'kana',
      guessState: ''
    },
    initialize: function() {
      return _.bindAll(this, 'random');
    },
    isWrong: function(guess) {
      var minLength;
      minLength = (_.max(this.get('romaji'), function(s) {
        return s.length || 0;
      })).length;
      return guess.length >= minLength && !_.any(this.get('romaji'), function(s) {
        return s.startsWith(guess.toLowerCase());
      });
    },
    isCorrect: function(guess) {
      return _.contains(this.get('romaji'), guess.toLowerCase());
    },
    random: function(callback) {
      var self;
      self = this;
      return $.ajax({
        url: "" + (this.get('charset')) + "/random/",
        data: {
          prevKana: this.get('kana')
        },
        success: function(flashCard) {
          flashCard.guessState = '';
          self.set(flashCard);
          if (callback != null) return callback();
        }
      });
    }
  });

  window.KanaFilter = Backbone.Model.extend({
    defaults: {
      hiragana: false,
      katakana: false
    },
    validate: function(attrs) {
      var desiredModel;
      desiredModel = _.extend(this.toJSON(), attrs);
      if (!desiredModel.hiragana && !desiredModel.katakana) {
        return "Must select at least one character set";
      }
    },
    select: function(charset) {
      switch (charset) {
        case 'hiragana':
          return this.save({
            hiragana: true,
            katakana: false
          });
        case 'katakana':
          return this.save({
            hiragana: false,
            katakana: true
          });
        case 'both':
          return this.save({
            hiragana: true,
            katakana: true
          });
        default:
          return false;
      }
    },
    url: function() {
      return '/kanafilter/';
    },
    kanaUrl: function() {
      if (this.get("hiragana") && this.get("katakana")) {
        return 'kana';
      } else if (this.get("hiragana")) {
        return 'hiragana';
      } else if (this.get("katakana")) {
        return 'katakana';
      } else {
        throw Error("invalid KanaFilter model state");
      }
    }
  });

  signalGuess = function(flashCard, guess, guessResult) {
    return $.ajax({
      url: "/guess/",
      type: "POST",
      data: {
        guess: guess != null ? guess.toLowerCase() : void 0,
        guessResult: guessResult,
        kana: flashCard.get('kana'),
        charset: flashCard.get('charset')
      }
    });
  };

  $(document).ready(function() {
    window.KanaFilterView = Backbone.View.extend({
      template: _.template($('#kanafilter-template').html()),
      events: {
        "click .select-button.unselected": "select"
      },
      initialize: function() {
        _.bindAll(this, 'render');
        return this.model.bind('change', this.render);
      },
      render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
      },
      select: function(e) {
        this.model.select($(e.target).data('charset'));
        return this;
      }
    });
    return window.FlashCardView = Backbone.View.extend({
      events: {
        "keyup input[type=text]": "guess"
      },
      initialize: function() {
        _.bindAll(this, 'render', 'guess');
        return this.model.bind('change', this.render);
      },
      guess: function(e) {
        var guess, self;
        guess = $(e.target).val();
        if (this.model.isCorrect(guess)) {
          this.$('.textframe').addClass('correct');
          this.$('.textframe').removeClass('wrong');
          this.$('input[type=text]').val('');
          signalGuess(this.model, guess, 'correct');
          this.model.set({
            guessState: 'correct'
          });
          self = this;
          return this.model.random(function() {
            clearTimeout(self.timerID);
            self.$('input[type=text]').focus();
            return self.timerID = setTimeout(function() {
              return self.$('.textframe').removeClass('correct');
            }, 888);
          });
        } else if (this.model.isWrong(guess)) {
          if (this.model.get('guessState') === '') {
            signalGuess(this.model, guess, 'wrong');
            this.model.set({
              guessState: 'wrong'
            });
          }
          return this.$('.textframe').addClass('wrong');
        } else {
          this.model.set({
            guessState: ''
          });
          return this.$('.textframe').removeClass('wrong');
        }
      },
      render: function() {
        this.$('p.kana').text(this.model.get('kana'));
        return this;
      }
    });
  });

  $(document).ready(function() {
    window.kanaFilter = new KanaFilter;
    window.flashCard = new FlashCard;
    window.kanaFilterView = new KanaFilterView({
      el: '#kana-filter',
      model: window.kanaFilter
    });
    window.flashCardView = new FlashCardView({
      el: '#flashcard',
      model: window.flashCard
    });
    kanaFilter.bind('change', function(model) {
      flashCard.set({
        charset: model.kanaUrl()
      });
      return flashCard.random(function() {
        return flashCardView.$('input[type=text]').focus();
      });
    });
    return kanaFilter.fetch({
      success: function() {
        kanaFilterView.render();
        return flashCardView.render();
      }
    });
  });

  $('#flashcard input[type=text]').live('focus', function() {
    if ($(this).hasClass('prompt')) {
      $(this).removeClass('prompt');
      return $(this).val('');
    }
  });

  $('#flashcard input[type=text]').live('blur', function() {
    if ($.trim($(this).val()) === '') {
      $(this).addClass('prompt');
      return $(this).val('Enter Romaji...');
    }
  });

  skipBtnTimerRunning = false;

  $('#flashcard .skip-button').live('click', function() {
    var skipBtnTimerID;
    if (!skipBtnTimerRunning) {
      signalGuess(flashCard, void 0, 'skip');
      skipBtnTimerRunning = true;
      $('#flashcard p.response').text(window.flashCard.get('romaji').join(', '));
      clearTimeout(skipBtnTimerID);
      return skipBtnTimerID = setTimeout(function() {
        $('#flashcard p.response').text('');
        $('#flashcard input[type=text]').val('');
        window.flashCard.random(function() {
          return flashCardView.$("input[type=text]").focus();
        });
        return skipBtnTimerRunning = false;
      }, 1000);
    }
  });

}).call(this);

