
if( !BAP ) { var BAP = {}; }

if (!BAP.lib) { BAP.lib = {}; }

BAP.lib.optout = {

    LOG_URL: "http://l.betrad.com/oo/p.gif",
    API_URL: "http://optout.betrad.com/api.php",

    OPTIN_EVENT: 0,
    OPTOUT_EVENT: 1,
    STATUS_EVENT: 2,

    version: "0.1",

    requests: [],
    events: [], // events that will get logged on unload

    /**
     * Callback function that fires for passing back the result of the optout operation from
     * the 3rd party. Only called if using the BAP Preferences API.
     */
    cbOptOutResponse: function(response) {
        BAP.trace(response);
        var req = BAP.lib.optout.requests[response.key];
        if (req.callback) {
            req.callback(req, response);
        }
    },

    /**
     * Callback function that fires when getting opt out status from 3rd party which has
     * implemented the BAP Preferences API.
     */
    cbGetOptOutStatusResponse: function(response) {
        BAP.trace(response);
        var req = BAP.lib.optout.requests[response.key];
        req.callback(req, response);
    },

    /**
     * Callback function that fires after URL lookup. Next action depends on the event type that
     * triggered the lookup
     */
    cbGetOptOutUrl: function(data) {
        BAP.trace(data);

        var d = BAP.lib.optout.requests[data.id];
        // copy loaded properties
        d.bap_api = data.bap_api;
        d.opt_out_url = data.opt_out_url;

        if (d.event_type == this.OPTOUT_EVENT || d.event_type == this.OPTIN_EVENT) {
            this.handleOptOutEvent(d);

        } else if (d.event_type == this.STATUS_EVENT) {
            this.handleStatusEvent(d);
        }
    },

    /**
     * Handle an opt out event. Called from the cbGetOptOutUrl() callback.
     */
    handleOptOutEvent: function(d) {
        this.addLogEvent(d);
        if (d.bap_api == true) {
            BAP.trace("Opting out using BAP API");
            BAP.dom.dropScript(d.opt_out_url + "?action=set&name=optout&value=" + d.event_type + "&callback=BAP.lib.optout.cbOptOutResponse&key=" + d.id);
        } else {
            BAP.trace("Opting out without BAP API");
            BAP.dom.dropPixelImage(d.opt_out_url);
        }
    },

    /**
     * Handle a status event. Called from the cbGetOptOutUrl() callback.
     */
    handleStatusEvent: function(d) {
        if (d.bap_api == true) {
            BAP.trace("Getting opt out status (" + d.opt_out_url + ")");
            BAP.dom.dropScript(d.opt_out_url + "?action=get&name=optout&callback=BAP.lib.optout.cbGetOptOutStatusResponse&key=" + d.id);
        } else {
            // can't get status, show generic status?
            BAP.trace("BAP API not supported; can't get opt out status");
        }
    },

    /**
     * Adds an event to be logged to the queue
     */
    addLogEvent: function(data) {
        if (data.params && data.params.log === false) {
            return;
        }
        this.log(data);
    },

    /**
     * Fire log pixel for each event in queue
     */
    log: function(ev) {
        if (ev !== undefined) {
            BAP.dom.dropPixelImage(BAP.lib.optout.getLogUrl(ev));
            return;
        }
        var evs = BAP.lib.optout.events;
        if (!evs || evs.length == 0) {
            return;
        }
        for (var i = 0; i < evs.length; i++) {
            var data = evs[i];
            BAP.dom.dropPixelImage(BAP.lib.optout.getLogUrl(data));
        }
    },

    /**
     * Create URL used for logging
     */
    getLogUrl: function(data) {
        var logUrl = BAP.lib.optout.LOG_URL + '?';
        logUrl += 'v=' + BAP.lib.optout.version;
        logUrl += '&r=' + escape(document.referrer);
        logUrl += '&c=' + data.id;
        logUrl += '&et=' + data.event_type;
        if (data.params && data.params.unique_visit) {
            logUrl += '&u=' + data.params.unique_visit;
        }
        if (data.params && data.params.selectall) {
            logUrl += '&s=' + data.params.selectall;
        }
        if (data.params && data.params.notice_id) {
            logUrl += '&n=' + data.params.notice_id;
        }
        if (data.params && data.params.pub_id) {
            logUrl += '&pid=' + data.params.pub_id;
        }
        if (data.params && data.params.owner_company_id) {
            logUrl += '&ocid=' + data.params.owner_company_id;
        }
        return logUrl;
    },

    /**
     * Get the opt out status for the given company.
     *
     * Only supported for companies implementing the BAP Preferences API
     */
    getOptOutStatus: function(companyId, callback, optOutUrl) {

        var rand = Math.floor(Math.random() * 100000);
        BAP.lib.optout.requests[rand] = {
            id: rand,
            callback: callback,
            event_type: this.STATUS_EVENT
        };

        if (optOutUrl === undefined) {
            // try to lookup the opt out url
            BAP.trace("No URL passed; looking up via AJAX");
            this.getOptOutUrl(companyId);

        } else {
            // use provided opt out url
            // if provided, it should always support BAP Preferences API
            BAP.trace("Got URL (" + optOutUrl + "); getting status");
            BAP.lib.optout.cbGetOptOutUrl({ id: rand, opt_out_url: optOutUrl, bap_api: true });
        }
    },

    /**
     * Tries to opt the user out of the specified company
     */
    doOptOut: function(eventType, companyId, callback, optOutUrl, apiSupport, params) {

        var rand = Math.floor(Math.random() * 100000);
        BAP.lib.optout.requests[rand] = {
            id: rand,
            callback: callback,
            event_type: eventType,
            params: params
        };

        if (optOutUrl === undefined) {
            // try to lookup the opt out url
            BAP.trace("No URL passed; looking up via AJAX");
            this.getOptOutUrl(companyId);

        } else {
            // use provided opt out url
            BAP.trace("Got URL (" + optOutUrl + "); opting out");
            BAP.lib.optout.cbGetOptOutUrl({ id: rand, opt_out_url: optOutUrl, bap_api: apiSupport });
        }
    },

    /**
     * Get URL for company.
     *
     * Sends an AJAX request to BAP servers to lookup the URL via companyId.
     *
     * Fires the cbGetOptOutUrl() callback
     */
    getOptOutUrl: function(companyId) {
       var url = BAP.lib.optout.API_URL + "/optout/company/" + companyId + "?callback=BAP.lib.optout.cbGetOptOutUrl";
       BAP.dom.dropScript(url);
    }

};

BAP.optin = function(companyId, callback, optOutUrl, apiSupport, params) {
    BAP.lib.optout.doOptOut(BAP.lib.optout.OPTIN_EVENT, companyId, callback, optOutUrl, apiSupport, params);
};

BAP.optout = function(companyId, callback, optOutUrl, apiSupport, params) {
    BAP.lib.optout.doOptOut(BAP.lib.optout.OPTOUT_EVENT, companyId, callback, optOutUrl, apiSupport, params);
};

BAP.optoutStatus = function(companyId, callback, optOutUrl) {
    BAP.lib.optout.getOptOutStatus(companyId, callback, optOutUrl);
};

BAP.dom = {

    addLoadEvent: function(func) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = func;
        } else {
            window.onload = function() {
                oldonload();
                func();
            };
        }
    },

    addUnloadEvent: function(func) {
        var oldonunload = window.onunload;
        if (typeof window.onunload != 'function') {
            window.onunload = func;
        } else {
            window.onload = function() {
                oldonunload();
                func();
            };
        }
    },

    // not currently used, here for testing
    dropIFrame: function(url) {
        BAP.trace("new iframe: " + url);
        var body = document.getElementsByTagName('body')[0];
        var iframe = document.createElement('iframe');
        // iframe.style.display = "none";
        iframe.setAttribute('src', url);
        body.appendChild(iframe);
    },

    dropScript: function(url) {
        BAP.trace("new script: " + url);
        var body = document.getElementsByTagName('body')[0];
        var span = document.createElement('span');
        span.style.display = "none";
        var scr = document.createElement('script');
        scr.setAttribute('src', url);
        span.appendChild(scr);
        body.appendChild(span);
    },

    dropPixelImage: function(url, callback) {
        BAP.trace("new pixel: " + url);
        var body = document.getElementsByTagName('body')[0];
        var img = document.createElement('img');
        img.setAttribute('src', url);
        img.setAttribute('height', '1');
        img.setAttribute('width', '1');
        img.style.display = "none";
        if (callback) {
            img.onload = callback;
        }
        body.appendChild(img);
    }

};

BAP.util = {

    debug: 0,

    trace: function(args) {
        if (this.enabled == 0) {
            return;
        }
        if (!args) {
            args = arguments;
        }
        try {
            if (args.length >= 1 || args.length <= 3) {
                var format = "-- BAP:  " + this.dump(args[0]);
                if (args.length == 1) {
                    console.log(format);
                } else if (args.length == 2) {
                    console.log(format, args[1]);
                } else if (args.length == 3) {
                    console.log(format, args[1], args[2]);
                }
            } else {
                alert("Improper use of trace(): " + args.length + " arguments");
            }
        } catch (e) { }
    },

    /**
     * Function : dump()
     * Arguments: The data - array,hash(associative array),object
     *    The level - OPTIONAL
     * Returns  : The textual representation of the array.
     * This function was inspired by the print_r function of PHP.
     * This will accept some data as the argument and return a
     * text that will be a more readable version of the
     * array/hash/object that is given.
     * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
     */
     dump: function(arr,level) {
        var dumped_text = "";
        if(!level) level = 0;

        //The padding given at the beginning of the line.
        var level_padding = "";
        for(var j=0;j<level+1;j++) level_padding += "    ";

        if(typeof(arr) == 'object') { //Array/Hashes/Objects
            for(var item in arr) {
                var value = arr[item];

                if(typeof(value) == 'object') { //If it is an array,
                    dumped_text += level_padding + "'" + item + "' ...\n";
                    dumped_text += dump(value,level+1);
                } else {
                    dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                }
            }
        } else { //Stings/Chars/Numbers etc.
            dumped_text = "'"+arr+"' ("+typeof(arr)+")";
        }
        return dumped_text;
    }

};

BAP.trace = function() {
    BAP.util.trace(arguments);
};

BAP.util.debug.enabled = 1;

