window.addEvent('domready', init);
var s = 0;
var badKeycodes = new Array(
    37, 38, 39, 40,       // arrow keys
    17, 18, 20, 224,      // shift, ctrl, alt, caps lock, cmd
    9, 33, 34, 144, 36,   // tab, page up/down, num lock, home
    35, 45,               // end, insert
    0
);


function init() {
    if (window.gecko) disableSpellcheck();
    initResize();
    initRadios();
    initAsync();
    preload();
}


function disableSpellcheck() {
    $$('textarea').each(function(textarea){
        textarea.setProperty('spellcheck', 'false');
    });
}


function initResize() {

    sizeToNumber = function(size){
        //converts a style size (ex: 10px) to a number. Hackish method
        return size.substring(0, size.length -2) * 1
    }

    var drag = new Drag.Multi({ handle: $('growBox') });

    x1el = $('pattern-input');
    x2el = $('string-textarea');
    x3el = $('matches-pre');
    x1 = x2 = x3 = 200;
    if(window.webkit) {
        x1 -= sizeToNumber(x1el.getStyle('padding-right')) + sizeToNumber(x1el.getStyle('padding-left'));
        x2 -= sizeToNumber(x2el.getStyle('padding-right')) + sizeToNumber(x2el.getStyle('padding-left'));
        x3 -= sizeToNumber(x3el.getStyle('padding-right')) + sizeToNumber(x3el.getStyle('padding-left'));
    }

    drag.add($('pattern-input'), { 
        x: { style: "width", direction: 2, limit: [x1, 9999] }
    });
    drag.add($('string-textarea'), { 
        x: { style: "width", direction: 2, limit: [x2, 9999] },
        y: { style: "height", direction: .5, limit: [50, 9999], grid: 1 }
    });
    drag.add($('matches-pre'), { 
        x: { style: "width", direction: 2, limit: [x3, 9999] },
        y: { style: "height", direction: .5, limit: [50, 9999], grid: 1 }
    });
}


function initRadios() {
    shedClasses = function(el) {
        el.removeClass('focus-checked');
        el.removeClass('focus-unchecked');
        el.removeClass('checked');
    }

    $$('#radios input').each(function(radio) {
        var label = radio.getNext();

        radio.addClass('replaced');
        label.addClass('replaced');

        if(radio.checked) label.addClass('checked');

        label.onclick = function() { 
            $$('#radios label').each(function(l) { shedClasses(l); });
            (function() { radio.checked = true; radio.focus(); }).delay(1);
        }

        radio.onfocus = function() {
            radio.hideFocus = true;
            (function() {
                if(radio.checked) label.addClass('focus-checked');
                else label.addClass('focus-unchecked');
            }).delay(1);
        }

        radio.onblur = function() { 
            (function () {
                shedClasses(label);
                if(radio.checked) label.addClass('checked');
            }).delay(1);
        }

        radio.onkeyup = function(evt) {
            if (window.ie) var charCode = event.keyCode;
            else var charCode = evt.keyCode;
            if(charCode == 13 || charCode == 32) {
                $$('#radios label').each(function(l) { shedClasses(l); });
                (function() { radio.blur(); radio.focus(); }).delay(1);
            }
        }
    });
}

var myRequest = new Ajax('http://regex.tastic.org/', {
    autoCancel: true,
    onRequest: function() {
        div = $('shortanswer-div');
        img = div.getElement('img');
        if (!img || img.getProperty('src') != 'spinner.gif') {
            div.setHTML('<img class="results-icon" src="spinner.gif" alt="" />');
        }
    },
    onSuccess: function() {
        htmlspecialchars = function(s) {
            s = s.replace(/&/g, "&amp;");
            s = s.replace(/</g, "&lt;");
            s = s.replace(/>/g, "&gt;");
            return s;
        }

        shorta = $('shortanswer-div');
        longa  = $('matches-pre');
        str    = $('string-textarea').value;

        result = Json.evaluate(this.response.text);

        if (result.error) {
            shorta.setHTML('<img class="results-icon" src="error.gif" alt="Error: " /> ' + result.error);
            longa.setHTML(htmlspecialchars(str));
        } else if (result.matches.length == 0) {
            shorta.setHTML('<img class="results-icon" src="cross.gif" alt="" /> No matches');
            longa.setHTML(htmlspecialchars(str));
        } else {
            shorta.setHTML('<img class="results-icon" src="tick.gif" alt="" /> ' + result.matches.length + ' match' + (result.matches.length == 1 ? '' : 'es'));
            result.matches.reverse();
            result.matches.each(function(match) {
                str = str.substring(0, match.pos + match.len) + '\x02' + str.substring(match.pos + match.len);
                str = str.substring(0, match.pos) + '\x01' + str.substring(match.pos);
            });
            str = htmlspecialchars(str);
            str = str.replace(/ ((\x01|\x02)*)(?=\s|$)/g, "\x03$1");

            str = str.replace(/\n/g, "\x05");
            str = str.replace(/\x01([^\x02]*)\x05/g, "\x01$1\x03\x05");

            str = str.replace(/\x01\x02/g, "<u><span class='firstchar'>\x04</span></u>");
            str = str.replace(/\x01(.)(.*?)\x02/g, '<u><span class="firstchar">$1</span>$2</u>');

            str = str.replace(/\x03/g, "&nbsp;");
            str = str.replace(/\x04/g, "&nbsp;");
            str = str.replace(/\x05/g, "<br />");

            longa.setHTML(str);

        }
    }
});

function checkKeycode(e) {
    if (window.ie) var keycode = event.keyCode;
    else var keycode = e.keyCode;
    if (!badKeycodes.contains(keycode)) {
        updateAsync();
    }
}

function updateAsync() {
    myRequest.options.data = $('form').toQueryString();
    myRequest.request();
}

function initAsync() {
    $('async').value = 1;
    $('pattern-input').onkeyup = checkKeycode;
    $('string-textarea').onkeyup = checkKeycode;
    $('form').onsubmit = function() { updateAsync(); return false; };
}

function preload() {
    new Asset.images(['tick.gif', 'cross,gif', 'error.gif', 'spinner.gif', 'radio-focus-checked.gif', 'radio-focus-unchecked.gif', 'radio-checked.gif', 'radio-unchecked.gif']);
}
