//** copyright (c) 2010 Reality Jockey Ltd. **//

//** define rjdj namespace **//
(function(event){
    if (!window.rjdj) {
        window.rjdj = {
            toString : function(){
                return this.__name__ + ' ' + this.version.join('.');
            },
            __name__ : 'RjDj JavaScript Library',
            version : [0,2,0],
            copyright : "Reality Jockey Ltd.",
            url : "http://rjdj.me"
        };
    }
}());


//** substitute console **//
(function(){
    if (!window.console || !console.firebug) {
        var names = ["log","debug","info","warn","error","assert","dir","dirxml","group","groupEnd","time","timeEnd","count","trace","profile","profileEnd","notifyFirebug"];
        window.console = {};
        for (var i = 0; i < names.length; ++i) {
            window.console[names[i]] = function(){};
        }
    };
})();


//** page cache **//
rjdj._cache = {
    toString : function(){
        return 'Cache';
    },
    scenes : {},
    recordings : {}
};


rjdj.exec = function exec(fname){
    console.log("Execute rjdj."+fname);
};

rjdj.DOM = {
    toString : function(){
        return "DOM";
    },
    jsattr : function(elem,attribute){
        var jsattr = {};
        var node = $(this);
        var attr = elem.getAttribute("js:attr");
        if (!attr) return null;
        var a = attr.split(";");
        for (var i=0; i<a.length; i++) {
            var kv = a[0].split("=");
            jsattr[kv[0]] = eval(kv[1]);
        }
        if (attribute) {
            return jsattr[attribute];
        } else {
            return jsattr;
        }
    }
};

rjdj.initAjaxLinks = function(dom){

    console.log("Execute rjdj.initAjaxLinks");

    $(".ajax-link", dom).unbind('click').bind('click', function(e){
            e.preventDefault();
            e.stopPropagation();
            var cssId = $(this).attr("target");
            var target = $("#"+cssId);
            $(this).unbind('click');
            $(this).css('opacity',0.65);
            var url = $(this).attr("href");
            var title = $(this).attr("title");
            var categ = rjdj.DOM.jsattr(this,"category");
            if (_gaq) {
                _gaq.push(['_trackEvent', categ, 'ajax', url, title]);
                console.log("GA",categ,'ajax',url,title);
            }
            $.get(url, function(res){
                    var wrapper = '<div class="ajax__wrapper" id="ajax__wrapper__'+ new Date().getTime() +'"></div>';
                    var node = target.wrap(wrapper).parent();
                    node.empty().append(res);
                    rjdj.__onDomLoad(node);
                });
        });

};

rjdj.initRollover = function(dom){

    console.log("Execute rjdj.initRollover");

    $(".iconInfo",dom).hover(
        function(){ $(this).siblings(".boxHelp").css("display", "block"); },
        function(){ $(this).siblings(".boxHelp").css("display", "none"); }
    );

};

rjdj.initDeleteButtons = function(dom){

    console.log("Execute rjdj.initDeleteButtons");

    $("a.delete",dom).click(function(e) {
            location.href = $(this).attr('href');
        }).confirm({msg:'Really?'});

};

rjdj.initSlugButtons = function(dom){

    console.log("Execute rjdj.initSlugButtons");

    $('a.makeslug',dom).click(function(e) {
       $(this).load($(this).attr("href"), function(data) {
            $('#' + $(this).attr('target')).html("<input value='" + data + "' id='slug-value' class='slug'/>");
            $('#slug-value').select();
        });
        e.preventDefault();
    });

};


rjdj.initEmbedLinks = function(dom){

    console.log("Execute rjdj.embedCode");

    $('.embed',dom).toggle(function(e){
            var url = $(this).attr("href");
            var id = $(this).attr("rid");
            var el = $(this);
            $("#embed_" + id).html("<textarea id='embed_" + id + "_input' class='embed-code'></textarea>");
            $.ajax({
                    'url' : url,
                    'type' : 'GET',
                    'success' : function(d, s) {
                        var res = d.replace(/$\s+/g,"").replace(/\n/g,"");
                        $("#embed_" + id + '_input').val(res);
                        $("#embed_" + id).fadeIn("slow");
                        $("#embed_" + id + "_input").select();
                    },
                    'error' : function(xhr){
                        $("#embed_" + id + '_input').val(xhr.responseText);
                        $("#embed_" + id).fadeIn("slow");
                    }
                });
            e.preventDefault();
        },function(){
            var id = $(this).attr("rid");
            $("#embed_" + id + "_input").fadeOut("slow", function(){
                    $("#embed_" + id).empty();
                });
        });

};

rjdj.initLikeButtons = function(dom){

    console.log("Execute rjdj.initLikeButtons");

    $('.favorites a', dom).click(function(e) {
        var target = $(this).attr('target');
        $.get($(this).attr('href'), {}, function(d) {
            $('#' + target).replaceWith(d);
        });
        e.preventDefault();
    });
};

rjdj.initAjaxForms = function(){

    console.log("Execute rjdj.initAjaxForms");

    $('form.ajax-form').bind('submit',function(e){
            e.preventDefault();
            var t = $('.ajax-form-target', $(this));
            $(this).ajaxSubmit(function(res){
                    t.empty().append(res);
                    var error = $('.errorlist');
                    if (error.count() > 0) {
                        window.scrollTo(0, error[0].offsetTop);
                    }
                });
            return false;
        });
};

rjdj.initTwitterConnect = function(){

    console.log("Execute rjdj.initTwitterConnect");

    $('#id_auto_twitter').bind('change',function(e){
            console.log('changed',this, this.checked);
            if (this.checked) {
                // save form and then connect to twitter
                $(this).parent().append('<div class="important">One moment, please! Connecting to Twitter ...</div>');
                $('form#profile-form').ajaxSubmit(function(){
                        window.setTimeout(function(){
                                window.location.href = "/oauth/twitter/login";
                            }, 250);
                    });
            }
        });

};

rjdj.RecordingMap = {

    POLYLINE_COLOR : "#0000ff",
    MAP_TARGET_ID : "recording_map",
    MAP_ZOOM_LEVEL : 15,

    geoData : [],
    geoPoints : [],
    map : null,

    toString : function(){
        return 'RecordingMap';
    },

    init : function(geoData,show){
        this.geoData = JSON.parse(geoData);
        var div = document.getElementById(this.MAP_TARGET_ID);
        if (show) {
            this.map = new google.maps.Map2(div);
            this.draw();
        } else {
            div.style.display = 'none';
        }
    },

    cleanGeoData : function(){
        var cleanGeoData = [];
        var last = [null,null];
        while (this.geoData.length) {
            var pt = this.geoData.pop();
            if (pt[0] == last[0] && pt[1] == last[1]) {
            } else {
                cleanGeoData.unshift(pt);
            }
            last = pt;
        }
        this.geoData = cleanGeoData;
        return this.geoData;
    },

    draw : function(){
        this.cleanGeoData();

        for (var i=0; i<this.geoData.length; i++) {
            var pt = this.geoData[i];
            this.geoPoints.push(new GLatLng(pt[0], pt[1]));
        }

        var polyline = new GPolyline(this.geoPoints, this.POLYLINE_COLOR, 5);
        this.map.addOverlay(polyline);
        this.map.addOverlay(new GMarker(this.geoPoints[0]));

        if (this.geoPoints.length > 1) {
            this.map.addOverlay(new GMarker(this.geoPoints[this.geoPoints.length-1]));
            this.fitToPoints();
        } else {
            var lat = this.geoData[this.geoData.length-1][0];
            var lng = this.geoData[this.geoData.length-1][1];
            var center = new google.maps.LatLng(lat,lng);
            this.map.setCenter(center,this.MAP_ZOOM_LEVEL);
        }
        this.map.addControl(new GSmallZoomControl3D());
    },

    fitToPoints : function(){
        var p = this.geoPoints;
        var lat=0, lng=0, maxLat=null, maxLng=null, i=0;
        for (i; i<p.length; i++) {
            var pin = p[i];
            lat += parseFloat(pin.lat());
            lng += parseFloat(pin.lng());
            if (maxLat) {
                if (pin.lat() > maxLat) maxLat = pin.lat();
            } else {
                maxLat = pin.lat();
            }
            if (maxLng) {
                if (pin.lng() > maxLng) maxLng = pin.lng();
            } else {
                maxLng = pin.lng();
            }
        }
        var avgLat = lat / p.length;
        var avgLng = lng / p.length;
        var minLat = avgLat - Math.abs(maxLat-avgLat);
        var minLng = avgLng - Math.abs(maxLng-avgLng);
        console.log(minLat,maxLat,avgLat);
        console.log(minLng,maxLng,avgLng);
        var bounds = new GLatLngBounds(new GLatLng(minLat,minLng), new GLatLng(maxLat,maxLng));
        var zoom = this.map.getBoundsZoomLevel(bounds,this.map.getSize());
        zoom = zoom > this.MAP_ZOOM_LEVEL ? this.MAP_ZOOM_LEVEL : zoom;
        var center = new google.maps.LatLng(avgLat,avgLng);
        console.log('center',center,'zoom',zoom);
        this.map.setCenter(center)
        this.map.setZoom(zoom);
    }

};

rjdj.FrontpageBox = {
    toString : function(){
        return "[object FrontpageBox]";
    },
    autoSlide : true,
    context : null,
    current : 1,
    speed : 6000,
    items : 0,
    interval : null,
    locked : false,
    _content : function(i){
        return $('#box-content-'+i, this.context);
    },
    _navigation : function(i){
        return $('#box-navigation-'+i, this.context);
    },
    init : function(context){
        var t = this;
        this.items = $('.box-navigation').size();
        $('.box-navigation',context).each(function(index,item){
                var i = index+1;
                $(this).bind('click',function(e){
                        e.preventDefault();
                        t.autoSlide = false;
                        $('.box-navigation').removeClass('selected');
                        $(this).addClass('selected');
                        t.slide(i);
                    });
            });
        this.context = context;
        this._content(1).show();
        this._navigation(1).addClass('selected');
        this.startAutoSlide();
        $('.box-content',context).bind('mouseover',function(){
                t.locked = true;
            });
        $('.box-content',context).bind('mouseout',function(){
                t.locked = false;
            });
    },
    slide : function(i){
        if (!this.autoSlide && this.interval) { this.stopAutoSlide(); };
        if (i == this.current) return;
        var t = this;
        this._content(this.current).fadeOut('slow', function(){
                t._content(i).fadeIn('slow');
                t.current = i;
            });
        $('.box-navigation').removeClass('selected');
        this._navigation(i).addClass('selected');
    },
    startAutoSlide : function(){
        var t = this;
        this.interval = window.setInterval(function(){
                if (t.locked) return;
                var i = (t.current < t.items) ? t.current+1 : 1;
                t.slide(i);
            },this.speed);
    },
    stopAutoSlide : function(){
        window.clearInterval(this.interval);
    }
};

rjdj.__onDomLoad = function execute(){

    var t = new Date().getTime();
    console.log("Execute rjdj.__onDomLoad");
    var dom = arguments[0] || $(document);

    this.initRollover(dom);
    this.initDeleteButtons(dom);
    this.initSlugButtons(dom);
    this.initEmbedLinks(dom);
    this.initLikeButtons(dom);
    this.initAjaxLinks(dom);
    this.initTwitterConnect(dom);
    this.initAjaxForms(dom);

    t = new Date().getTime() - t;
    console.info("Loaded in "+t+"ms", this, dom);

};

$(document).ready(function(){rjdj.__onDomLoad();});

String.prototype.strf = function(){
    var self = this;
    for (var i=0; i<arguments.length; i++) {
        var r = arguments[i];
        self = self.replace(/%s/, String(r));
    }
    return self;
};

Array.prototype.contains = function(value) {
    for (var i=0; i<this.length;i++) {
        if (this[i] === value) {
            return true;
        }
    }
    return false;
};

Array.prototype.index = function(value) {
    for (var i=0; i<this.length;i++) {
        if (this[i] === value) {
            return i;
        }
    }
    return null;
};

Array.prototype.groupBy = function(k,i) {
    var key = k || null;
    var indexed = i || false;
    if (!key) return this;
    var a = [];
    var b = indexed ? {} : [];
    for (var i=0; i<this.length; i++) {
        var v = this[i][k];
        if (!a.contains(v)) {
            a.push(v);
            if (indexed) {
                b[v] = [];
            } else {
                b.push([]);
            }
        }
        if (indexed) {
            b[v].push(this[i]);
        } else {
            var j = a.index(v);
            b[j].push(this[i]);
        }
    }
    return b;
};

Array.prototype.orderBy = function(k,o) {
    var key = k || null;
    var order = (o && ["asc","desc"].contains(o)) ? o : "asc";
    if (!key) return this;
    this.sort(function(a,b){
            var ak = a[key];
            var bk = b[key];
            if (!ak || !bk) return 0;
            if (ak == bk) return 0;
            return (ak > bk) ? 1 : -1;
        });
    if (order == "desc") return this.reverse();
    return this;
};

var show_stats = function stats(){
    var node = $("#sqldebug");
    if (node.size() > 0) {
        var str = node.text();
        var sql = eval(str);
        console.log(sql);
        sql.orderBy('time','desc');
        for (var i=0; i<sql.length; i++) {
            console.log(parseInt(i+1,10), sql[i].time, sql[i]);
        }
    }
};
