// load our google apis
google.load("language", "1");
google.load("jquery", "1.3.2");

google.setOnLoadCallback(function() {
    var to = new TranslationOrgy();
});

var Translator = function(text, config) {
    this.text            = text;
    this.startTxt        = text;
    this.steps           = new Object();
    this.curStep         = 0;
    this.maxStep         = 32;
    this.inLng           = 'de';
    this.transLng        = 'ja';
    this.stepCallback    = function(resultTxt, from, to, stepNo, steps) {}; // is called on every step
    this.finishCallback  = function(resultTxt, startTxt) {}; // is called after last step
    this.timeoutCallback = function() {}; // is called after maxStep is exceeded
    this.errorCallback   = function(errorObj) {}; // is called on API errors
    
    if(typeof config.onStep == 'function') {
        this.stepCallback = config.onStep;
    }
    if(typeof config.onFinish == 'function') {
        this.finishCallback = config.onFinish;
    }
    if(typeof config.onError == 'function') {
        this.errorCallback = config.onError;
    }
    if(typeof config.onTimeout == 'function') {
        this.timeoutCallback = config.onTimeout;
    }
    if(typeof config.inLng == 'string') {
        this.inLng = config.inLng;
    }
    if(typeof config.transLng == 'string') {
        this.transLng = config.transLng;
    }
    this.fromLng        = this.inLng;
    this.toLng          = this.transLng;
    
    this.steps[this.fromLng] = new Array();
    this.steps[this.toLng]   = new Array();
    
    // does the actual translation
    this.translate = function() {
        var instance = this;
        window.setTimeout(function() { instance.translateStep(); }, 300);
    };
    
    this.getPrevStep = function(lng) {
        return this.steps[lng][this.steps[lng].length-2];
    };
    
    this.translateStep = function() {
        this.curStep++;
        
        var instance = this;
        google.language.translate(
            this.text, 
            this.fromLng, 
            this.toLng,
            function(result) {
                if (result.translation) {
                    var tmp_lang;
                    
                    // save this step
                    instance.steps[instance.toLng].push(result.translation);
                    
                    instance.stepCallback(
                        result.translation,
                        instance.fromLng,
                        instance.toLng,
                        instance.curStep,
                        instance.steps
                    );
                    
                    instance.text = result.translation;
                    
                    // last step...
                    if((instance.toLng == instance.inLng) && (instance.getPrevStep(instance.toLng) == result.translation)) {
                        instance.finishCallback(
                            result.translation,
                            instance.startTxt
                        );
                    }
                    // ...or timeout...
                    else if(instance.curStep >= instance.maxStep) {
                        instance.timeoutCallback();
                    }
                    // ...or continue
                    else {
                        instance.translate();
                    }
                    
                    // swap to <-> from
                    tmp_lang = instance.fromLng;
                    instance.fromLng = instance.toLng;
                    instance.toLng = tmp_lang;
                } else {
                    
                    // error
                    instance.errorCallback(result.error);
                }
            }
        );
    };
};

var TranslationOrgy = function() {
    this.languages = {
        'de': 'Deutsch',
        'ja': 'Japanisch',
        'en': 'Englisch'
    };
    
    this.init = function() {
        $('#translation').empty().hide();
        
        // create our form
        var instance = this;
        $('<form/>')
            .attr({
                'id': 'translationform'
            })
            .bind(
                'submit', 
                function() {
                    instance.translateSubmit();
                    return false;
                }
            )
            .append('<input type="text" id="text" value="Ein Satz deiner Wahl" />')
            .appendTo('#translation');
        
        this.inputPreVal($('#text'));
        $('#translation').fadeIn();

        google.language.getBranding('branding');
        
        var instance = this;
        window.setTimeout(
            function() { instance.initHash(); }, 
            250
        );
    };
    
    this.translateSubmit = function() {
        var text = $('#text').attr('value');
        $('#text').fadeOut();
        $('#steps').remove();
        $('#pre_transl').empty();
        $('#after_transl').empty();
        $('<ul/>').attr('id', 'steps').appendTo('#translation');
        
        // and create our translator
        var instance = this;
        var transl = new Translator(
            text,
            {
                onError:   function(errorObj) { return instance.error(errorObj); },
                onFinish:  function(resultTxt, startTxt) { return instance.finish(resultTxt, startTxt); },
                onStep:    function(resultTxt, from, to, stepNo, steps) { return instance.step(resultTxt, from, to, stepNo, steps); },
                onTimeout: function() { return instance.timeout(); }
            }
        );
        
        this.addListElement('So, hier fangen wir an:', text, 0);
        window.location.hash = '#' + text;
        
        // ...and translate
        transl.translate();
        return false;
    };
    
    this.error = function(errorObj) {
        alert(
            'Oh, something went wrong? ' + 
            '(Google Translate API returned error: ' + 
            errorObj.code + 
            ': ' + errorObj.message + 
            ")\nTry shortening your sentence."
        );
        this.resetTxt();
    };
    
    this.timeout = function() {
        this.resetTxt();
        this.collapse(
            'Hm... es sieht so aus, als würde es hier kein Ende mehr geben...', 
            '#FF0000'
        );
    };
    
    this.step = function(resultTxt, from, to, stepNo, steps) {
        this.addListElement(
            'Jetzt von ' +
            this.getLngLong(from) +
            ' nach ' +
            this.getLngLong(to),
            resultTxt,
            stepNo
        );
    };
    
    this.finish = function(resultTxt, startTxt) {
        this.resetTxt();
        if(startTxt == resultTxt) {
            this.collapse('Gib es doch zu, der Satz ergab schon vorher keinen Sinn!');
        } else {
            this.collapse('Hey... Glückwunsch! Dieser Satz wurde erfolgreich von jedem Sinn befreit!', '#397900');
        }
    };
    
    this.initHash = function() {
        if(window.location.hash.length > 1) {
            //this.prevHash = window.location.hash;
            var text = unescape(window.location.hash.substr(1));
            
            $('#text').attr('value', text);
            $('#translationform').submit();
            
        }
    };
    
    this.addListElement = function(info, txt, id) {
        $('<li/>')
            .html('<span class="info"></span><br /><span class="txt"></span>')
            .attr('id', 'list-' + id)
            .hide()
            .prependTo('#steps')
            .fadeIn();
        $('#list-' + id + ' .info')
            .text('(' + id + ') ' + info);
        $('#list-' + id + ' .txt')
            .text(txt);
    };
    
    this.inputPreVal = function(ele, txt) {
        if(typeof txt != 'string') {
            txt = 'Einen Satz deiner Wahl eingeben...';
        }
        $(ele).bind(
            'focus', 
            function() {
                if(!$(this).data('focused')) {
                    $(this).attr('value', '').css('color', '#000000').data('focused', true);
                }
            }
        )
        .bind(
            'keydown', 
            function() { 
                $(this).trigger('focus'); 
            }
        )
        .css('color', '#6E6E6E')
        .data('focused', false)
        .attr('value', txt);
    };
    
    this.resetTxt = function() {
        $('#text').attr('value', '').fadeIn();
        this.inputPreVal($('#text'));
    };
    
    this.getLngLong = function(shortName) {
        if(typeof this.languages[shortName] != 'undefined') {
            return this.languages[shortName];
        } else {
            return shortName;
        }
    };
    
    this.collapse = function(msg, col) {
        $("#steps li:gt(0):not(:last-child)").slideUp('slow');
        $('#steps li:eq(0)').css('color', col);
        $('<h2/>').text(msg).appendTo('#pre_transl');
        this.inputPreVal($('#text'), 'Noch einen Versuch?');
        $('<a/>').attr({
            'href': '#',
            'id': 'expand',
            'title': 'Alle Schritte anzeigen'
        }).bind('click', function() {
            $("#steps li:gt(0):not(:last-child)").slideToggle('slow');
            return false;
        }).text('Alle Schritte anzeigen...').appendTo('#after_transl');
        // share
        var share = $(
            '<fieldset id="share">' + 
            '<legend>Diese Übersetzung an Freunde weiterschicken</legend>' + 
            '<p>Diese Übersetzung ist besonders lustig? ' + 
            'Schicke diesen Link per E-Mail, Twitter oder ' +
            'Instant Messenger an deine Freunde weiter, ' + 
            'damit sie auch darüber lachen können!</p>' + 
            '</fieldset>'
        ).appendTo('#after_transl');
        $('<input/>')
            .val(window.location.href)
            .bind(
                'click',
                function() {
                    this.select();
                }
            )
            .appendTo(share);
    };
    
    this.init();
};
