function SlashHandler() {
    this.symbols = new Array() ["/", "?", "&"];
    this.handle = function(focus) {
        hideHint();
        showTables();
        if (focus) currentHint.focus();
    };
}

function DotHandler() {
    this.symbols = new Array() ["."];
    this.handle = function(focus) {
        var tableName = parseName();
        hideHint();
        if (tableName) {
            showCommands(tableName, true);
        } else {
            showCommands(tableName, false);
        }
        if (focus) currentHint.focus();
    };
}

function CurlyBracketHandler() {
    this.symbols = new Array() ["{"];
    this.handle = function(focus) {
        var tableName = parseName();
        if (tableName) {
            /*var f = $('query');
            if (isCaretAtEnd(f)) {
                // close curly brackets
                var pos = caretAt(f);
                insertAtCaret(f, "}");
                setCaretTo(f, pos);
            }*/
            hideHint();
            showTable(tableName);
            if (focus) currentHint.focus();
        }
    };
}

function CommaHandler() {
    this.symbols = new Array() [","];
    this.handle = function(focus) {
        var posEscape = findSymbol("}", true);
        var pos = findSymbol("{", true);
        if (pos > -1) {
            if (posEscape == -1 || pos > posEscape) {
                var tableName = parseInput(false, pos);
                if (tableName) {
                    hideHint();
                    showTable(tableName);
                    if (focus) currentHint.focus();
                }
            }
        }
    };
}

function UniversalHandler() {
    this.symbols = new Array();
    this.handle = function(focus) {
        if (handleInit(focus)) {
            return;
        }
        if (handleColumnSorting(focus)) {
            //return;
        }
    };

    function handleInit(focus) {
        var pos = caretAt(ID('query'));
        var posSlash = findSymbol("/", true);

        if (posSlash > -1 && pos == posSlash+2) {
            showTables();
            match();
            return true;
        }

        return false;
    }

    function handleColumnSorting(focus) {
        var posEscape = findSymbol("}", true);
        var pos = findSymbol("{", true);
        if (pos > -1) {
            if (posEscape == -1 || pos > posEscape) {
                var tableName = parseInput(false, pos);
                if (tableName) {
                    var columnName = parseInput(false, -1);
                    if (columnName) {
                        for (var i = 0; i < metadata.columns[tableName].length; i++) {
                            var name = metadata.columns[tableName][i];
                            if (name == columnName) {
                                hideHint();
                                showColumnSorting();
                                if (focus) currentHint.focus();
                                return true;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }
}

function HandlerMap() {
    var handlerMap = {
        "/": new SlashHandler(),
        "?": new SlashHandler(),
        "&": new SlashHandler(),
        ".": new DotHandler(),
        "{": new CurlyBracketHandler(),
        ",": new CommaHandler(),
        "___UNIVERSAL___": new UniversalHandler()
    };

    this.get = function(key) {
        return handlerMap[key];
    };

    this.getUniversal = function() {
        return handlerMap["___UNIVERSAL___"];
    };
}

var handlerMap = new HandlerMap();

function handlerTest() {
    handlerMap.get("/").handle(0);
    handlerMap.get("?").handle(0);
    handlerMap.get("&").handle(0);
    handlerMap.get(".").handle(0);
    handlerMap.get("{").handle(0);
    handlerMap.get(",").handle(0);
}

