﻿/*
    document.lazy_writer
    BSD license.
*/

document.lazy_writer = (function(){
    function lazy_writer(url, callback, option){
        var session = {
            script_count  : 0,
            call_count    : 0,
            context       : [],
            stash         : {},
            timer         : null,
            delay         : 0,
            current_script: null
        };
        if(option){
            for(var key in option){
                session[key] = option[key];
            }
        }
        var f = function(script, str){
            session.call_count++;
            if(session.timer){
                clearTimeout(session.timer)
            }
            // run other script -> force write old script
            if(session.current_script && session.current_script != script){
                callback.call(session, session.context.join(""));
                session.context = [];
                session.current_script = script;
                session.script_count++;
            } else if(session.current_script != script){
                session.current_script = script;
                session.script_count++;
            }
            session.context.push(str);
            session.timer = setTimeout(function(){
                callback.call(session, session.context.join(""));
                session.context = [];
            }, session.delay);
        };
        lazy_writer.register(url, f);
    }
    lazy_writer.writers = {};
    lazy_writer.patterns = [];
    lazy_writer.register = function(expr, callback){
        var pair;
        if(typeof expr == 'string'){
            lazy_writer.writers[expr] = callback;
            pair = [function(url){return url.indexOf(expr) != -1}, callback];
        }
        if(typeof expr == 'function'){
            pair = [expr, callback];
        }
        if(expr.constructor == RegExp){
            pair = [function(url){return expr.test(url)}, callback];
        }
        pair && lazy_writer.patterns.push(pair);
    };
    lazy_writer.exists = function(url){
        return lazy_writer.fetch(url) ? true : false;
    };
    lazy_writer.fetch = function(url){
        if(lazy_writer.writers.hasOwnProperty(url)){
            return lazy_writer.writers[url]
        }
        for(var i=0,pair;pair=lazy_writer.patterns[i];i++){
            if(pair[0](url)) return pair[1]
        }
    };
    var original_document_write = document.write;
    document._write = document.write;
    function getCurrentScript(){
        return (function (e) {
            if(e.nodeName.toLowerCase() == 'script') return e;
            return arguments.callee(e.lastChild)
        })(document);
    }
    document.write = function(){
        var current = getCurrentScript();
        var writer;
        if(writer = lazy_writer.fetch(current.src)){
            var args = Array.prototype.slice.call(arguments);
            writer(current, args.join(""));
        } else {
            try{
                // doesn't work in IE and Safari
                original_document_write.apply(document, arguments);
            } catch(e){
                var args = Array.prototype.slice.call(arguments);
                try {
                    original_document_write(args.join("")); // for IE
                } catch(e){
                    document._write(args.join("")); // for Safari
                }
            }
        }
    };
    return lazy_writer;
})();
