/*
savvyAds.js
javascript delivery for savvy ads platform

implementation:

 - call this script with a script tag at the bottom of any page requesting ad units.
 - include a empty div tag with a class of "savvyAds" where an ad unit is desired.
 - units will be numbered 1 through n as they appear in the DOM/markup.
 
*/

var savvyAds = {

    init: function() {
                       
        savvyAds.ts0 = new Date().getTime();            
        savvyAds.call();   // makes the call to BWP    
    },

    call: function() {

        // automatically try to detect domain if no domain is set
        var domain = location.href.replace(/^http:\/\/.*?(\w+?\.\w+?)[:|\/].*$/, "$1");
        if (domain == 'com.com' || domain == 'cnet.com') {
            domain = location.href.replace(/^http:\/\/.*?(\w+?\.\w+?\.com)[:|\/].*$/, "$1");
        }

        var json = 'async';
        if (savvyAds.options && savvyAds.options.domain) {
            if (savvyAds.options.domain != domain) {
                domain = savvyAds.options.domain;
                json = 'sync';
            }
        } else {
            json = 'sync';
        } 

        var refurl = location.href;
                
        savvyAds.request = 'http://bwp.' + domain + '/search';
        savvyAds.request += '?refurl=' + escape(refurl);
        savvyAds.request += '&json=' + json;
        savvyAds.request += '&debugview=1';   // current hack to get complete debug info      
        savvyAds.request += '&ts='+savvyAds.ts0;
        
        // sniff dw parameters 
        savvyAds.dwParams = savvyAds.sniffDwParams();
        for (key in savvyAds.dwParams) {
            savvyAds.request += '&dw-' + key+ '=' + savvyAds.dwParams[key];
        }

        savvyAds.calltype = json;
        savvyAds.ts1 = new Date().getTime();  
                
        if (json == 'async') {  // asyncronous call using invisible iframe (same domain)
            
            document.domain = domain.replace(/^.*?(\w+?\.\w+?)$/, "$1");
            var args = 'height="1" width="1" style="display:none"';
            document.write('<iframe src="'+savvyAds.request+'" '+args+'></iframe>');
            
        } else {  // syncronous call using blocking script tag (any domain)
            
            document.write('<scr'+'ipt src="'+savvyAds.request+'"></scr'+'ipt>');
        }
    },

    load: function(results) {
    
        savvyAds.ts2 = new Date().getTime();  
        savvyAds.results = results;
 
        // make sure DOM's ready
        savvyAds.domReady();       
    },
    
    render: function() {
       
        savvyAds.units = savvyAds.getUnits();  // collects all empty div units on the page    
        savvyAds.ts3 = new Date().getTime();  
    
        var results = savvyAds.results;
        
        // set if client is local
        var local = results.meta.server ? 1 : 0;

        if (results.units.length) {
            
            // inject styles
            var style = document.createElement('div')
            style.innerHTML = '<br/><style>'+results.style+'</style>';   
            document.getElementsByTagName('head')[0].appendChild(style);     
            
            // iterate through all returned units and populate empty divs            
            for (unit = 0; unit < results.units.length; unit++) {
            
                if (savvyAds.units[unit] && results.units[unit]) {
             
                    savvyAds.units[unit].innerHTML = results.units[unit]; 
                    
                    // add IE fix to ul element for proper calc
                    savvyAds.units[unit].childNodes[1].style.overflow = 'auto';
                    // resize if clipping                     
                    if (savvyAds.units[unit].childNodes[1].offsetHeight > savvyAds.units[unit].offsetHeight) {

                        savvyAds.units[unit].resize();
                    }   
                }
            }
            
            savvyAds.ts4 = new Date().getTime();
              
            // alert client of undisplayed units if they're local
            if (results.units.length > savvyAds.units.length) {
                
                var message = location.href; 
                message += ': expected '+results.units.length+' ad units on the page';
                message += ' and found only '+ savvyAds.units.length;
                savvyAds.log(message);
                if (local) savvyAds.alert(message);
            }
        }
            
        // interate though all empty ad units and close them
        for (unit = 0; unit < savvyAds.units.length; unit++) {
             
            if (!savvyAds.units[unit].innerHTML) {
                    
                savvyAds.units[unit].style.display = 'none';
            }
        }

        // render placement meta/debug data if old debugview=1 is set
        if (location.href.match(/debugview=1/)) savvyAds.debug();
        
        // log time stats for testing
        var callMade = savvyAds.ts1 - savvyAds.ts0;
        var resultsLoaded = savvyAds.ts2 - savvyAds.ts0;
        var domReady = savvyAds.ts3 - savvyAds.ts0;
        var unitsRendered = savvyAds.ts4 - savvyAds.ts0;
        var message = callMade+' ms, ';
        message += resultsLoaded+' ms, ';
        message += domReady+' ms, ';
        message += unitsRendered+' ms';
//        savvyAds.log(message);
    },

    // finds all divs with class "savvyAds" and returns them in an array
    getUnits: function() {

        var adUnits = new Array();
        var allDivs = document.getElementsByTagName('div');
        var total = allDivs.length;
        var regex = new RegExp("(^|\\\\s)savvyad_unit(\\\\s|$)");
        for (i = 0, j = 0; i < total; i++) {
       
            if (regex.test(allDivs[i].className)) {
 
                adUnits[j] = allDivs[i];
                adUnits[j].id = 'savvyad_unit' + (j+1);
                
                // method to increase unit height if cropped
                adUnits[j].resize = function() {

                    var self = this;
                    var ads = self.childNodes[1];
                    var somePadding = 10;

                    if (ads.offsetHeight > self.offsetHeight - somePadding) {

                        self.style.height = parseInt(self.offsetHeight) + 5 + 'px';
                        setTimeout(function(){ self.resize() }, 1);
                        
                    } else {
                        
                        self.style.height = 'auto';
                    }                    
                };
                
                j++;
            }
        }
        return adUnits;

    },
    
    sniffDwParams: function() {

        var dwParams = {};
        
        if (typeof(DW) != 'undefined' && DW.pageParams) {
            
            dwParams = DW.pageParams;
            
        } else {
               
            var allImgs = document.getElementsByTagName('img');
            var total = allImgs.length;
            var regex = new RegExp('dw\.com\.com');
            for (i = 0; i < total; i++) {
       
                if (regex.test(allImgs[i].src)) {
 
                    var params = allImgs[i].src.split(/&/);
                    var totalParams = params.length;
                    params[0] = params[0].replace(/^.*?\?/, '');
                 
                    for (j = 0; j < totalParams; j++) {
                                 
                        var keyValue = params[j].split('=');
                        dwParams[keyValue[0]] = keyValue[1];
                    } 
                }
            }
        }
        
        return dwParams;
    },
 
    alert: function(message) {

        var alert = document.createElement('div');
        alert.style.position = 'absolute';
        alert.style.top = 0;
        alert.style.right = 0;
        alert.style.backgroundColor = '#eda654';
        alert.style.zIndex = '999';
        alert.id = 'savvyAdsAlert';
        alert.style.opacity = '0.85';
        alert.onclick = function() { this.style.display = 'none';}
        
        alert.innerHTML = '<div style="color:#333;font-size:14px;padding:4px;">savvyAds internal alert</div>';
        alert.innerHTML += '<div style="padding:4px;color:#000;font-size:12px;">'+message+'</div>';
        document.body.appendChild(alert);
    },

    log: function(message) {
      
        var log = new Image(1,1);
        message = '[savvyAds] '+ message;
        message = escape(message);
        log.src = 'http://lumberjack.search.com/log?msg='+message;
    },
    
    // renders meta/debug data if it exists   
    debug: function() {
       
        if (!savvyAds.results.meta) return;

        var meta = savvyAds.results.meta;
   
        // load css for debug view
        var head = document.getElementsByTagName('head')[0];
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.type = 'text/css';
        link.href = 'http://i.i.com.com/cnwk.1d/css/se/adsdebug.css';
        head.appendChild(link);
 
        for (i = 0; i < savvyAds.units.length; i++) {
            
            var unitId = document.createElement('div');
            unitId.className = 'unitid';
            unitId.innerHTML = 'unit '+(i+1)+'/'+savvyAds.units.length+'<p>results '+meta.unit.order[i]+'</p>';
            var highlight = document.createElement('div');
            highlight.className = 'highlight';
            savvyAds.units[i].appendChild(highlight);
            savvyAds.units[i].appendChild(unitId);
        }

        var debugView = document.createElement('div');
        var h2 = document.createElement('h2');
        debugView.id = 'savvyads_debug';
        h2.innerHTML = 'savvyAds';
        debugView.appendChild(h2);
        document.body.appendChild(debugView);

        // build request data section            
        var requestDiv = document.createElement('div');
        requestDiv.id = 'request';
        var requestHTML = '<p><b>call type:</b> '+savvyAds.calltype+'</p>';
        requestHTML += '<p><b>units on page:</b> '+savvyAds.units.length+'</p>';
        requestHTML += '<p><b>ad call:</b> <a target="_new" href="'+savvyAds.request+'">';
        requestHTML += savvyAds.request+'</a></p>';
        requestDiv.innerHTML = requestHTML;
        debugView.appendChild(requestDiv);

        // build response data section
        var responseDiv = document.createElement('div');
        responseDiv.id = 'response';
        var responseHTML = '<p><b>server id:</b> '+meta.server+'</p>';
        responseHTML += '<p><b>units returned:</b> '+savvyAds.results.units.length+'</p>';
        
        for (i = 0; i < meta.sources.length; i++) {
           
            responseHTML += '<p><b><a href="'+meta.sources[i].request;
            responseHTML += '">'+meta.sources[i].name+'</a></b>';
            var plural = meta.sources[i].results == 1 ? '' : 's';
            var fetchtime = '<b>'+meta.sources[i].fetchTime+'</b> sec';
            responseHTML += ' (<b>'+meta.sources[i].results
            responseHTML += ' result'+plural+'</b> in '+fetchtime+')';
            
            if (meta.sources[i].name.match(/google/i)) {
                
                var details = '<li><b>client:</b> '+meta.sources[i].clientId+'</li>';
                details += '<li><b>channel:</b> '+meta.sources[i].channelId+'</li>';
                
                if (meta.sources[i].browseKey != null) {
                    
                    details += '<li><b>keyword:</b> '+meta.sources[i].browseKey+'</li>';
                }
                responseHTML += '<ul>'+details+'</ul>';              
            }
            responseHTML += '</p>';      
        }

        responseDiv.innerHTML = responseHTML;
        debugView.appendChild(responseDiv);

        // build stats section
        var callMade = savvyAds.ts1 - savvyAds.ts0;
        var resultsLoaded = savvyAds.ts2 - savvyAds.ts0;
        var domReady = savvyAds.ts3 - savvyAds.ts0;
        var unitsRendered = savvyAds.ts4 - savvyAds.ts0;
        var statsDiv = document.createElement('div');
        statsDiv.id = 'stats';
        var statsHTML = '<p><b>'+callMade+' ms</b> (call made)</p>';
        statsHTML += '<p><b>'+resultsLoaded+' ms</b> (call returned)</p>';
        statsHTML += '<p><b>'+domReady+' ms</b> (dom ready)</p>';
        statsHTML += '<p><b>'+unitsRendered+' ms</b> (units rendered)</p>';
        statsDiv.innerHTML = statsHTML;
        debugView.appendChild(statsDiv);
        
    },
    
    domReady: function() {

        if (window.addEventListener)
        
        	window.addEventListener('load', savvyAds.render, false);

        else if (window.attachEvent) {
            
        	window["eloadsavvyAds.render"] = savvyAds.render;
        	window["loadsavvyAds.render"] = function() { window["eloadsavvyAds.render"]( window.event ); }
        	window.attachEvent("onload", window["eloadsavvyAds.render"] );
        }
    }
}    

// old image tracking function
function img_track(url) {

    var i = new Image(1,1);
    i.src = url;
}
