var RubyConsole = DUI.Class.create({
    init: function(rubyInterpreter, rubyConsoleInput, rubyConsoleDisplay) {
        this.rubyInterpreter = rubyInterpreter;
        this.rubyConsoleInput = rubyConsoleInput;
        this.rubyConsoleDisplay = rubyConsoleDisplay;
    },

    startObserving: function() {
        var self = this;
        
        this.rubyConsoleDisplay.consoleContainer.focus(function(event) {
            self.focus();
        })

        this.rubyConsoleInput.line.keydown(function(event) {
            switch (event.keyCode) {
                case 10: // enter along with special key
                case 13: // enter
                    return self.handleInput(event);
                case 38: // up
                    self.rubyConsoleInput.upInHistory();
                    return false;
                case 40: // down
                    self.rubyConsoleInput.downInHistory();
                    return false;
                case 27: // escape
                    self.rubyConsoleInput.clearInputLine();
                    return false;
                default:
                    return true;
            }
        });
    },

    clear: function() {
        this.rubyConsoleInput.clearInputLine();
        this.rubyConsoleDisplay.clearDisplay();
    },

    focus: function() {
        this.rubyConsoleInput.focus();
    },

    handleInput: function(event) {
        if (event.ctrlKey) {
            this.prepareForMultilineInput();
        } else {
            this.evaluateInput();
        }
        return false;
    },

    prepareForMultilineInput: function() {
        this.rubyConsoleInput.prepareForNextLine();
        this.focus();
    },

    evaluateInput: function() {
        var inputLine = this.rubyConsoleInput.line.val();
        this.rubyConsoleInput.displayPleaseWait(true);
        this.rubyConsoleInput.addToHistory(inputLine);
        this.rubyConsoleDisplay.displayRubyScript(inputLine);
        this.rubyConsoleInput.clearInputLine();
        var self = this;
        this.rubyInterpreter.eval(inputLine, {
            async: false,
            callback: function(evalResult) { self.displayEvalResult(evalResult); }
        });
    },

    displayEvalResult: function(evalResult) {
        this.rubyConsoleInput.displayPleaseWait(false);
        this.rubyConsoleDisplay.displayResult(evalResult);
        this.rubyConsoleInput.blur();
        this.rubyConsoleInput.focus();
    }
});

var RubyConsoleFactory = DUI.Class.create({
    init: function(rubyInterpreter, consoleContainerSelector) {
        this.rubyInterpreter = rubyInterpreter;
        this.consoleContainerSelector = consoleContainerSelector;
        var self = this;
        rubyInterpreter.inputLines({
            async: false,
            callback: function(inputLines) {
                self.setNewInstance(inputLines);
            }
        });
    },

    setNewInstance: function(inputLines) {
        var rubyConsoleDisplay = new RubyConsoleDisplay(this.consoleContainerSelector);
        var rubyConsoleInput = new RubyConsoleInput(this.consoleContainerSelector, inputLines);
        this.rubyConsole = new RubyConsole(this.rubyInterpreter, rubyConsoleInput, rubyConsoleDisplay);
        return this.rubyConsole;
    }
});