'use strict';

var Backbone = require('backbone'),
    PasswordGenerator = require('../util/password-generator'),
    CopyPaste = require('../comp/copy-paste'),
    Locale = require('../util/locale');

var GeneratorView = Backbone.View.extend({
    el: 'body',

    template: require('templates/generator.hbs'),

    events: {
        'click': 'click',
        'mousedown .gen__length-range': 'generate',
        'mousemove .gen__length-range': 'lengthChange',
        'change .gen__length-range': 'lengthChange',
        'change .gen__check input[type=checkbox]': 'checkChange',
        'click .gen__btn-ok': 'btnOkClick',
        'change .gen__sel-tpl': 'templateChange',
        'click .gen__btn-refresh': 'newPass'
    },

    valuesMap: [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28,30,32,48,64],

    presets: null,
    preset: null,

    initialize: function () {
        this.createPresets();
        var preset = this.preset;
        this.gen = _.clone(_.find(this.presets, function(pr) { return pr.name === preset; }));
        $('body').one('click', this.remove.bind(this));
        this.listenTo(Backbone, 'lock-workspace', this.remove.bind(this));
    },

    render: function() {
        var canCopy = document.queryCommandSupported('copy');
        var btnTitle = this.model.copy ? canCopy ? Locale.alertCopy : Locale.alertClose : Locale.alertOk;
        this.renderTemplate({ btnTitle: btnTitle, opt: this.gen, presets: this.presets, preset: this.preset });
        this.resultEl = this.$el.find('.gen__result');
        this.$el.css(this.model.pos);
        this.generate();
        return this;
    },

    createPresets: function() {
        this.presets = [
            { name: 'Default', length: 16, upper: true, lower: true, digits: true },
            { name: 'Pronounceable', length: 10, lower: true, upper: true },
            { name: 'Med', length: 16, upper: true, lower: true, digits: true, special: true, brackets: true, ambiguous: true },
            { name: 'Long', length: 32, upper: true, lower: true, digits: true },
            { name: 'Pin4', length: 4, digits: true },
            { name: 'Mac', length: 17, upper: true, digits: true, special: true },
            { name: 'Hash128', length: 32, lower: true, digits: true },
            { name: 'Hash256', length: 64, lower: true, digits: true }
        ];
        if (this.model.password && (!this.model.password.isProtected || this.model.password.byteLength)) {
            var derivedPreset = { name: 'Derived' };
            _.extend(derivedPreset, PasswordGenerator.deriveOpts(this.model.password));
            for (var i = 0; i < this.valuesMap.length; i++) {
                if (this.valuesMap[i] >= derivedPreset.length) {
                    derivedPreset.length = this.valuesMap[i];
                    break;
                }
            }
            if (derivedPreset.length > this.valuesMap[this.valuesMap.length - 1]) {
                derivedPreset.length = this.valuesMap[this.valuesMap.length - 1];
            }
            this.presets.splice(1, 0, derivedPreset);
            this.preset = 'Derived';
        } else {
            this.preset = 'Default';
        }
        this.presets.forEach(function(pr) {
            pr.pseudoLength = this.valuesMap.indexOf(pr.length);
            pr.title = Locale['genPreset' + pr.name];
        }, this);
    },

    click: function(e) {
        e.stopPropagation();
    },

    lengthChange: function(e) {
        var val = this.valuesMap[e.target.value];
        if (val !== this.gen.length) {
            this.gen.length = val;
            this.$el.find('.gen__length-range-val').html(val);
            this.optionChanged('length');
            this.generate();
        }
    },

    checkChange: function(e) {
        var id = $(e.target).data('id');
        if (id) {
            this.gen[id] = e.target.checked;
        }
        this.optionChanged(id);
        this.generate();
    },

    optionChanged: function(option) {
        if (this.preset === 'Custom' ||
            this.preset === 'Pronounceable' && ['length', 'lower', 'upper'].indexOf(option) >= 0) {
            return;
        }
        this.preset = this.gen.name = 'Custom';
        this.$el.find('.gen__sel-tpl').val('');
    },

    generate: function() {
        this.password = PasswordGenerator.generate(this.gen);
        this.resultEl.text(this.password);
        var isLong = this.password.length > 32;
        this.resultEl.toggleClass('gen__result--long-pass', isLong);
    },

    btnOkClick: function() {
        var selection = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(this.resultEl[0]);
        selection.removeAllRanges();
        selection.addRange(range);
        CopyPaste.copy(this.password);
        this.trigger('result', this.password);
        this.remove();
    },

    templateChange: function(e) {
        var name = e.target.value;
        this.preset = name;
        var preset = _.find(this.presets, function(t) { return t.name === name; });
        this.gen = _.clone(preset);
        this.render();
    },

    newPass: function() {
        this.generate();
    }
});

module.exports = GeneratorView;
