function get_el(el)
{
	return (typeof(el) == "string") ? el = document.getElementById(el) : el
}

function hide(el)
{
	get_el(el).style.display = 'none' 
}

function show(el)
{
	get_el(el).style.display = '' 
}

function toggle(el, show_el)
{
	el = get_el(el)

	if ( show_el === undefined )
		show_el = (el.style.display == 'none')

	if ( show_el )
		show( el )
	else 
		hide( el )
}

function enable(el, enable)
{
	if ( enable === undefined ) enable = true;

	el = get_el(el)
	el.disabled = !enable
}

function openAppletWindow(url, name, width, height)
{
    w = window.open(url,
            name,
            'width=' + width + ',height=' + height + ',menubar=no,resizable=yes,scrollbars=no,status=1');
    w.focus();
    return false;
}

function addEvent(obj, key, fn, prefix)
{
	var old = obj[key];
	obj[key] = function()
	{
        if (prefix)
            fn.apply(this, arguments)

		if (old)
		{
			old.apply(this, arguments)
		}

        if (!prefix)
            fn.apply(this, arguments)
	}
}

function addOnLoad(fn, prefix)
{
	addEvent(window, 'onload', fn, prefix);
}



/*
 * Adds for various link sites
 */

function addToFacebook()
{
	window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(location.href)+
				'&amp;t='+encodeURIComponent(document.title),
				'sharer',
				'toolbar=0,status=0,width=626,height=436')
	return false
}

function addToStumbleUpon()
{
	var url = 'http://www.stumbleupon.com/submit?url=' + encodeURIComponent(location.href) + 
				'&title='  + encodeURIComponent(document.title)
	window.open(url,'stumble')
	return false
}

function addToDigg()
{
	var url = 'http://digg.com/submit?phase=2&url=' + encodeURIComponent(location.href) +
					'&title=' + encodeURIComponent(document.title)
	window.open(url, 'digg')
	return false
}

function addToDelicious()
{
	var url = 'http://del.icio.us/post?v=4&noui&jump=close&url=' + 
				encodeURIComponent(location.href) + 
				'&title='+encodeURIComponent(document.title)
	window.open(url, 'delicious','toolbar=no,width=700,height=400')
	return false
}

addOnLoad( function()
{
	// Insert contact details
	var mailto = document.getElementById("contact")
	if ( mailto )
	{
		var name = "game.pixies"
		var domain = "gmail.com"
		var email = name + "@" + domain
		mailto.href="mailto:" + email
	}
} )

/*
 * Loads another script
 */

function load_js(src)
{
    document.write("<script type='text/javascript' src='" + src + "'></script>");
}

/*
 * LTLP reader/writer
 */

function encode_ltlp(data)
{
    var have_shim2js = typeof(shim2js) != 'undefined';
    var pair = have_shim2js && shim2js.pair;
    var symbol = have_shim2js && shim2js.symbol;

    var inner_encode = function(data)
    {
        if (data === null)
            return '()';
        if (data === false)
            return '#f';
        if (data === true)
            return '#t';
        switch (data.constructor)
        {
        case Number:
            return '' + data;
        case String:
            return '"' + data.replace(/(["\\])/g, '\\$1') + '"';
        case Array:
        {
            var res = '(';
            var i, len = data.length;
            if (len > 0)
                res += inner_encode(data[0]);
            for (i=1; i<len; ++i)
                res += ' ' + inner_encode(data[i]);
            return res + ')';
        }
        case pair:
        {
            var res = '(' + inner_encode(data.car);
            data = data.cdr;
            while (data != null)
            {
                res += ' ' + inner_encode(data.car);
                data = data.cdr;
            }
            return res + ')';
        }
        case symbol:
            return data.name;
        }
    }

    return inner_encode(data);
}

function LtlpReader(as_shim)
{
    this.feed = function(data)
    {
        var start = 0;
        var end = data.length;
        while (start < end) start = this.handler.feed(data, start, end);
    }

    this.has_data = function()
    {
        return this.collection_handler.collected.length > 0;
    }

    this.get_data = function()
    {
        return this.collection_handler.collected.shift();
    }

    // internals

    var reader = this;

    var CollectionHandler = function()
    {
        this.collected = [];

        this.finished = function(value)
        {
            this.collected.push(value);
            reader.handler = new UnknownHandler(this);
        }

        reader.handler = new UnknownHandler(this);
    }

    var UnknownHandler = function(owner)
    {
        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (c == '#')
                {
                    reader.handler = new BooleanHandler(owner);
                    return start;
                }
                if (c == '.' || c == '-' || (c >= '0' && c <= '9'))
                {
                    reader.handler = new NumberHandler(owner);
                    return start - 1;
                }
                if (c == '"')
                {
                    reader.handler = new StringHandler(owner);
                    return start;
                }
                if (/[-_a-zA-Z]/.test(c))
                {
                    reader.handler = new KeywordHandler(owner);
                    return start - 1;
                }
                if (c == '(')
                {
                    reader.handler = new ListHandler(owner);
                    return start;
                }
            }
        }
    }

    var BooleanHandler = function(owner)
    {
        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (c == 't') owner.finished(true);
                else if (c == 'f') owner.finished(false);
                else throw 'bad ltlp input';
                return start;
            }
        }
    }

    var NumberHandler = function(owner)
    {
        var buf = '';

        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (c == '.' || c == '-' || (c >= '0' && c <= '9'))
                    buf += c;
                else
                {
                    owner.finished(parseFloat(buf));
                    return start - 1;
                }
            }
            return start;
        }
    }

    var StringHandler = function(owner)
    {
        var buf = '';
        var esc = false;

        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (esc)
                {
                    esc = false;
                    buf += c;
                }
                else if (c == '\\')
                    esc = true;
                else if (c == '"')
                {
                    owner.finished(buf);
                    return start;
                }
                else
                    buf += c;
            }
            return start;
        }
    }

    var KeywordHandler = function(owner)
    {
        var buf = '';

        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (/[-_a-zA-Z]/.test(c))
                    buf += c;
                else
                {
                    owner.finished(as_shim ? shim2js.string2symbol(buf) : buf);
                    return start - 1;
                }
            }
            return start;
        }
    }

    var ListHandler = function(owner)
    {
        var collected = [];

        this.feed = function(data, start, end)
        {
            while (start < end)
            {
                var c = data.charAt(start++);

                if (c == ')')
                {
                    owner.finished(as_shim ? shim2js.vector2list(collected) : collected);
                    return start;
                }
                else if (!/\s/.test(c))
                {
                    reader.handler = new UnknownHandler(this);
                    return start - 1;
                }
            }
            return start;
        }

        this.finished = function(value)
        {
            collected.push(value);
            reader.handler = this;
        }
    }

    this.collection_handler = new CollectionHandler();
}

function jshim_make_bridge(applet, onconnect_proc, handler_proc)
{
    var onconnect = function(other_side)
    {
        var reader = new LtlpReader(true);
        jshim_send_msg_to_js = function(ltlp)
        {
            reader.feed(ltlp + ' ');
            return other_side(reader.get_data());
        }
        applet.shim_call1(onconnect_proc, true);
    }

    var ltlp_writer = function(msg)
    {
        applet.shim_call1(handler_proc, encode_ltlp(msg));
    }

    if (typeof(connect_games_room_bridge) == 'undefined')
    {
        connect_games_room_bridge = function(other_side)
        {
            onconnect(other_side);
            return ltlp_writer;
        }
    }
    else onconnect(connect_games_room_bridge(ltlp_writer));
}
