var sql;
var basic = "/api/SELECT DISTINCT kvk, bedrijfsnaam, adres, postcode, plaats, type, anbi, status, kvks, sub, website FROM kvk";
var results;
var serveroffset;
var from;
var order = '';
var orderby = '';

function addslashes ( str ) {
        return (str+'').replace(/([\\'])/g, "\\$1").replace(/\0/g, "\\0");
}

function isType(data) {
    if ($("#inputsearch").val().indexOf("adres:") === 0) {
        return 'adres';
    } else if ($("#inputsearch").val().indexOf("adresplaats:") === 0) {
        return 'adresplaats';
    }

    return null;
}

function prepend(nummer, lengte, karakter) {
    if (nummer === null) {
        return '';
    } else {
        // http://www.electrictoolbox.com/pad-number-zeroes-javascript/
        var str = '' + nummer;
        while (str.length < lengte) {
            str = karakter + str;
        }
        return str;
    }
}

function append(nummer, lengte, karakter) {
    if (nummer === null) {
        return '';
    } else {
        // http://www.electrictoolbox.com/pad-number-zeroes-javascript/
        var str = '' + nummer;
        while (str.length < lengte) {
            str = str + karakter;
        }
        return str;
    }
}


function volgorde(type) {
    order = type;
    search();
//    $("#searchkvk").submit();
}

function zoek(e,postcode) {
    var e = e || window.event;
    e.stopPropagation();
    if (e.ctrlKey) {
        var postcode6PP = /([0-9]{4}[A-Za-z]{2})/i;
        var kvk = /([0-9]{7,8})/;

        var kvkm = kvk.exec(postcode);
        if (kvkm !== null) {
            $.get("/suggest/"+kvkm[0], function(data){alert(data);});
        } else {
            var postcode6PPm = postcode6PP.exec(postcode);
            if (postcode6PPm !== null) {
                $.get("/suggest/"+kvkm[0], function(data){alert(data);});
            }
        }
    } else {
        $("#terug").hide();
        $("#meer").hide();
        $("#inputsearch").val(postcode);
        $("#searchkvk").submit();
    }
    return false;
}

function render(offset) {
    if (offset < 0) {
        if (serveroffset === 0) {
            offset = 0;
        } else {
            serveroffset = serveroffset - 200;
            offset = 200 + offset;
        }
    }

    $(".results").remove();

    for (var x = offset; (x < results[0]['RESULT']['ROWS'].length && x < (offset + 10)); x++) {         
        $("#result").append('<tr class="results"><td><a href="/'+prepend(results[0]['RESULT']['ROWS'][x][8], 8, '0')+'" onclick="javascript:zoek(event,this.innerHTML); return false;">'+prepend(results[0]['RESULT']['ROWS'][x][8], 8, '0')+'</a></td>'+
                '<td>'+prepend(results[0]['RESULT']['ROWS'][x][9], 4, '0')+'</td>'+
                '<td>'+(results[0]['RESULT']['ROWS'][x][10] !== null ?
                        '<a target="_new" href="http://'+results[0]['RESULT']['ROWS'][x][10]+'"><span class="name">'+results[0]['RESULT']['ROWS'][x][1]+'</span><span class="www">...naar website</span></a>'
                    : results[0]['RESULT']['ROWS'][x][1])+'</td>'+
                '<td><a href="/adres:'+results[0]['RESULT']['ROWS'][x][2]+'" onclick="javascript:zoek(event,\'adres: \'+this.innerHTML); return false;">'+results[0]['RESULT']['ROWS'][x][2]+'</a><br />'+
                '<a href="/'+results[0]['RESULT']['ROWS'][x][3]+'" onclick="javascript:zoek(event,this.innerHTML); return false;">'+results[0]['RESULT']['ROWS'][x][3]+'</a> '+
                results[0]['RESULT']['ROWS'][x][4]+'</td>'+
                '<td>'+(results[0]['RESULT']['ROWS'][x][5] !== null ? results[0]['RESULT']['ROWS'][x][5] : '')+'</td>'+
                '<td>'+(results[0]['RESULT']['ROWS'][x][6] == 'true' ? 'Ja' : 'Nee')+'</td>'+
                '<td>'+(results[0]['RESULT']['ROWS'][x][7] !== null ?
                    (results[0]['RESULT']['ROWS'][x][7] == 'Faillissement' ?
                    '<a target="_new" style="color: #f00;" href="http://www.faillissementen.com/registernl.php?kvk='+results[0]['RESULT']['ROWS'][x][8]+'">'+
                    results[0]['RESULT']['ROWS'][x][7]+
                    '</a>'
                    :'<span style="font-weight: bold; color: #f00;">'+results[0]['RESULT']['ROWS'][x][7]+'</span>')
                    :'Actief')+'</td></tr>');
    }

    from = offset;

    if (x < results[0]['RESULT']['ROWS'].length) {
        $("#meer").show();
    } else {
        if (results[0]['RESULT']['ROWS'].length != 0 &&
                (results[0]['RESULT']['ROWS'].length % 200) === 0) {
            serveroffset = serveroffset + 200;
            $.get(sql+" OFFSET "+serveroffset+";", {}, callback, "json");
            $("#zoeken").show();
        }

        $("#meer").hide();
    }

    if (x > 10) {
        $("#terug").show();
    } else {
        $("#terug").hide();
    }
}

var callback2 = function (data, textStatus) {
    results = data;
    try {
        if (data[0]['RESULT']['ROWS'].length > 0) {
            $("#zoeken").hide("slow");
            $("#result").show();
            render(0);
        } else {
                var suggestie = '';
            $("#result").hide();
            $("#zoeken").hide("slow");
            if (isType($("#inputsearch").val()) === null) {
                var kvk = /([0-9]{7,8})/;
                var kvkm = kvk.exec($("#inputsearch").val());
                if (kvkm !== null) {
                    suggestie = 'de suggestie is gemeegenomen!'
                    $.get("/suggest/"+kvkm[0]);
                } else {
                    suggestie = '<br />Op adres zoeken kan met <a onclick="javascript:zoek(event,this.innerHTML); return false;">adres: '+$("#inputsearch").val()+'</a>';
                }
            }
            $("#intro").after('<p class="results">Helaas (nog) geen resultaten... '+suggestie+'</p>');
        }
    } catch(e) {
        alert("Er is een fout opgetreden, je mag hem melden op Twitter @openkvk.\n"+e);
    }
};
        

var callback = function (data, textStatus) {
    results = data;

    try {
        if (data[0]['RESULT']['ROWS'].length > 0) {
            $("#zoeken").hide("slow");
            $("#result").show();
            render(0);
        } else {
            var sql = ''
            var suggestie = '';
            $("#result").hide();
            $("#zoeken").hide("slow");
            if (isType($("#inputsearch").val()) === null) {
                var kvk = /([0-9]{7,8})/;
                var kvklong = /([0-9]{11,12})/;
                var kvkm = kvk.exec($("#inputsearch").val());
                var kvklongm = kvklong.exec($("#inputsearch").val());

                if (kvklongm !== null) {
                    $("#zoeken").show();
                    sql = basic+" WHERE kvk.kvk = "+kvklongm[0];
                } else {
                    if (kvkm !== null) {
                        $("#zoeken").show();
                        sql = basic+" WHERE kvk.kvks = "+kvkm[0];
                    } else {
                        suggestie = '<br />Op adres zoeken kan met <a onclick="javascript:zoek(event,this.innerHTML); return false;">adres: '+$("#inputsearch").val()+'</a>';
                    }
                }
            }
            if (sql != '') {
                $.get(sql+" LIMIT 1;", {}, callback2, "json");
            } else {
                $("#intro").after('<p class="results">Helaas (nog) geen resultaten... '+suggestie+'</p>');
            }
        }
    } catch(e) {
        alert("Er is een fout opgetreden, je mag hem melden op Twitter @openkvk.\n"+e);
    }
};

var sphinxfirst = function (data, textStatus) {
    results = data;

    try {
        if (data[0]['RESULT'].length > 0) {
            kvknummers = results[0]['RESULT'][0];
            for (var x = 1; x < results[0]['RESULT'].length; x++) {
                kvknummers = kvknummers +','+results[0]['RESULT'][x];
            }
            sql = basic+" WHERE kvk.kvk IN ("+kvknummers+")"+orderby;
        } else {
            slashed = addslashes($("#inputsearch").val());
            sql = basic+" WHERE kvk.bedrijfsnaam ILIKE '%25"+slashed+"%25'"+orderby;
        }
        $.get(sql+" OFFSET "+serveroffset+";", {}, callback, "json");
    } catch(e) {
        alert("Er is een fout opgetreden in Sphinxfirst, je mag hem melden op Twitter @openkvk.\n"+e);
    }
};

function search() {
    var adresplaats = /^adresplaats:[ ]?(.+),[ ]?(.+)/;
    var adres = /^adres:[ ]?(.*)/;
    var postcode6PP = /([0-9]{4}[A-Za-z]{2})/i;
    var postcode4PP = /([0-9]{4})/;
    var kvk = /([0-9]{7,8})/;
    var kvklong = /([0-9]{11,12})/;
    var adresplaatsm = adresplaats.exec($("#inputsearch").val());
    var adresm = adres.exec($("#inputsearch").val());
    var postcode6PPm = postcode6PP.exec($("#inputsearch").val());
    var postcode4PPm = postcode4PP.exec($("#inputsearch").val());
    var kvkm = kvk.exec($("#inputsearch").val());
    var kvklongm = kvklong.exec($("#inputsearch").val());
    serveroffset = 0;
    sql = '';


    if (order != '') {
        orderby = ' ORDER BY '+order;
    } else {
        orderby = '';
    }

    orderby = orderby + ' LIMIT 200';

    $(".results").remove();

    if (adresplaatsm !== null) {
        $("#zoeken").show();
        slashed1 = addslashes(adresplaatsm[1]);
        slashed2 = addslashes(adresplaatsm[2]);
        sql = basic+" WHERE kvk.adres ILIKE '%25"+slashed1+"%25' AND kvk.plaats ILIKE '%25"+slashed2+"%25'"+orderby;
    } else {
        if (adresm !== null) {
            $("#zoeken").show();
            slashed = addslashes(adresm[1]);
            sql = basic+" WHERE kvk.adres ilike '"+slashed+"%25'"+orderby;
        } else {
            if (kvklongm !== null) {
                $("#zoeken").show();
                sql = basic+" WHERE kvk.kvk = "+kvklongm[0]+orderby;
            } else {
                if (kvkm !== null) {
                    $("#zoeken").show();
                    sql = basic+" WHERE kvk.kvks = "+kvkm[0]+orderby;
                } else {
                    if (postcode6PPm !== null) {
                        $("#zoeken").show();
                        sql = basic+" WHERE kvk.postcode = UPPER('"+postcode6PPm[0]+"')"+orderby;
                    } else {
                        if (postcode4PPm !== null) {
                            $("#zoeken").show();
                            sql = basic+" WHERE kvk.postcode LIKE '"+postcode4PPm[0]+"%25'"+orderby;
                        } else {
                            $("#zoeken").show();
                            slashed = addslashes($("#inputsearch").val());
                            sql = "/api/SELECT DISTINCT x.kvk, x.bedrijfsnaam, x.adres, x.postcode, x.plaats, x.type, not(x.anbi is null), x.status, x.kvks, x.sub, x.website FROM (select * FROM sphinx_searchIndex('"+slashed+"', 'openkvk') as fts, kvk where kvk.kvk = fts.id) as x"+orderby;
                        }
                    }
                }
            }
        }
    }
    if (sql != '') {
        $.get(sql+" OFFSET "+serveroffset+";", {}, callback, "json");
    }
}

$(document).ready(function(){
        $("#searchkvk").submit(function(){
            if ($("#inputsearch").val() == 'Zoek op naam, kvk of postcode' || $("#inputsearch").val() == '') {
                return false;
            } else {
                window.location="/"+$("#inputsearch").val();
                // search();
                return false;
            }

            return false;
        });

        var query = /^http(s)?\:\/\/(www\.)?openkvk\.nl\/(.+)$/;
        var querym = query.exec(window.location);
        if (querym !== null) {
            if (querym[3].match('.html$') != '.html') {
                $("#inputsearch").val(unescape(querym[3]));
                search();
//            $("#searchkvk").submit();
            }
        }
});

var term = null;

var monetdb_help = [   
    '\\?     - show this message',
    '\\>file - save response in file, or stdout if no file is given',
    '\\h     - show the readline history',
    '\\q     - terminate session'
];

           
function termHandler() {
    var line = this.lineBuffer;
    this.newLine();
    switch (line) {
        case '\\q':
            $("#topbar").animate({height: "5px"}, 300, function() { term.close(); } );
            return;
        case '\\?':
            this.write(monetdb_help);
            this.prompt();
            break;
        case '\\h':
            this.write(this.history);
            this.prompt();
            break;
        default:
            var query = /(SELECT .*)( LIMIT [0-9]+)?;$/i
            var querym = query.exec(line);
            if (querym === null) {
                /* query is clearly not finished, merging lines will be interesting */
                this.write('Only single line SELECT statements are supported.');
                this.prompt();
            } else {
                var myurl = '/api/';
                if (querym[2] == undefined) {
                    myurl += querym[1]+' LIMIT 10;';
                } else {
                    myurl += line;
                }
                this.send({url: myurl, method: "get", callback: mySocketCallback});
            }
            
            break;
    }
}



function mySocketCallback() {
   var obj
   if (this.socket.status == 403) {
       this.write("This query isn't allowed by the backend.\n");
       this.prompt();
       return;
   }
   try {
       obj = jQuery.parseJSON(this.socket.responseText);
   }
   catch (err)
   {
        this.write("Can't parse reply.\n");
        this.prompt();
        return;
   }
   if (obj[0]['MONETDB_ERROR'] === undefined) {
        tuples = obj[0]['RESULT']['ROWS'].length;

        if (tuples > 0) {
            /* Obviously, you are completely free to shoot in a pull-request that pretty prints this :) */
            var columns = obj[0]['RESULT']['HEADER'].length;
            var length_columns = [];
            var prepend_columns = [];

            for (var x = 0; x < obj[0]['RESULT']['HEADER'].length; x++) {
                length_columns[x] = obj[0]['RESULT']['HEADER'][x].length;
            }

            intonly = /int$/
            for (var x = 0; x < obj[0]['RESULT']['TYPES'].length; x++) {
                if (intonly.exec(obj[0]['RESULT']['TYPES'][x]) !== null) {
                    prepend_columns[x] = true;
                } else {
                    prepend_columns[x] = false;
                }
            }

            for (var x = 0; x < obj[0]['RESULT']['ROWS'].length; x++) {
                for (var y = 0; y < columns; y++) {
                    if (obj[0]['RESULT']['ROWS'][x][y] === null) {
                        len = 4;
                    } else {
                        len = obj[0]['RESULT']['ROWS'][x][y].length;
                    }

                    if (length_columns[y] < len) {
                        length_columns[y] = len;
                    }
                }
            }
            
            cache = '+'
            for (var x = 0; x < obj[0]['RESULT']['HEADER'].length; x++) {
                cache += append('', length_columns[x]+2, '-')+'+';
            }
            cache += '\n';

            this.write(cache);

            this.write('|');
            for (var x = 0; x < obj[0]['RESULT']['HEADER'].length; x++) {
                this.write(' '+append(obj[0]['RESULT']['HEADER'][x], length_columns[x], ' ')+' |');
            }
            this.write('\n+');
            for (var x = 0; x < obj[0]['RESULT']['HEADER'].length; x++) {
                this.write(append('', length_columns[x]+2, '=')+'+');
            }
            this.write('\n');

            for (var x = 0; x < obj[0]['RESULT']['ROWS'].length; x++) {
                this.write('|');
                for (var y = 0; y < columns; y++) {
                    val = obj[0]['RESULT']['ROWS'][x][y], length_columns[y];
                    if (val === null) {
                        val = 'NULL';
                    }
                    if (prepend_columns[x] === true) {
                        this.write(' '+prepend(val, length_columns[y], ' ')+' |');
                    } else {
                        this.write(' '+append(val, length_columns[y], ' ')+' |');
                    }
                }
                this.write('\n');
            }
            this.write(cache);
        }
        this.write(tuples+' tuples\n');
   } else {
       this.write(obj[0]['MONETDB_ERROR']);
   }
   this.prompt();
}

function termExit() {
    $("#topbar").height("5px");
    $("#termwrap").hide();
    document.onkeypress = keyHandler;
}


function monetdb(database) {
    return 'Welcome to mjsclient, the MonetDB/SQL interactive terminal in javascript\n'+
           'Database: MonetDB v11.5.0, \''+database+'\'\n'+
           'Type \\q to quit, \\? for a list of available commands';
}

function keyHandler(e)
{
    var pressedKey;
    if (document.layers) {
        pressedKey = e.which;
    } else {
        if (e == null) { e = window.event; }
        pressedKey = e.keyCode;
    }
    pressedCharacter = String.fromCharCode(pressedKey);
    if (pressedCharacter == '~') {
        document.onkeypress = null;
        if (term == null) { term = new Terminal( {x: 0, y: 0, handler: termHandler, termDiv: 'term', ps: 'sql>', greeting: monetdb('openkvk'), crsrBlinkMode: true, crsrBlockMode: false, exitHandler: termExit } ); }

        term.open();
        $("#termwrap").show();
        $("#topbar").animate({height: $(document).height()}, 300, function() { $("#topbar").height('100%'); });
    }
}

document.onkeypress = keyHandler;

