/*
 * Include this file, preferably near the bottom of an HTML source page/template.
 *
 *    Fetch ads from the adserver:           ATLASAds.request(argument_object);
 *    Display the loaded ads:                foreach (ad requested_ads) { 
 *                                             ATLASAds.showAd(ad);
 *                                             ATLASAds.moveAd(ad);
 *                                           }
 *
 * Notes: 
 *  Because ATLASAds.request() uses document.write, you must close the script
 *    tag in which it's called before calling ATLASAds.showAd()/ATLASAds.moveAd().
 *
 *  The argument_object passed to ATLASAds.request can contain these properties:
 *
 *    area       (string)  - page name, like "ridepage", "toprides", etc. 
 *    country    (string)  - country acronym, if available
 *    domain     (string)  - ???
 *    event_name (string)  - an event name (for area="events")
 *    group_id   (number)  - a group id, on groups pages   
 *    group_tags (array)   - a list of groups tag values
 *    member_id  (string)  - a member id
 *    positions  (array)   - a list of ad position names
 *    ride_id    (number)  - a ride(page) id
 *    site       (string)  - always 'cardomain',
 *    sortby     (string)  - for search results
 *    sotw       (string)  - 'true' or 'false', for ride pages
 *    state      (string)  - state/province acronym, if available
 *    url        (string)  - default is 'http://media.cardomain.com/bserver'
 *    vehicle    (string)  - a car make name or make.model, e.g. "ford", "honda.civic"
 *    year       (number)  - a year number
 *
 * NOTE: the string property values and the group_tags array values should be
 *       composed of letter, number, underscore, and '.' characters only. Any
 *       other character values are converted to underscore ('_').
 * 
 * Example:
 *  ATLASAds.request({
 *    area        : "homepage",
 *    member_id   : "dev_a",
 *    group_tags  : ["You WILL","all","need","ReAdInG","glasses"],
 *    positions   : ['top','frame1','position2','x22']
 *  });
 *
 *
 * The method ATLASAds.setAssociateGroups is included to cover situations
 * where the default values for Associated Ad Groups ("associated creatives") 
 * are incorrect. The default values are
 *
 * 'top','frame1','expand','skin'     : for the L++ group 
 * 'position3','bottom3'              : for the inverse L group   
 *
 * To define a different ad group or groups, you must define them all at once:
 *
 *  ATLASAds.setAssociateGroups([['group1a','group1b'],['group2a','group2b','group2c']]);
 * 
 */    
                                         
ATLASAds = {
  specs : {
    area          : null,
    country       : null,
    domain        : null,
    event_name    : null,
    group_id      : null,
    group_tags    : null,
    member_id     : null,
    pageurl       : null,
    positions     : [],
    ride_id       : null,
    site          : 'cardomain',
    sortby        : null,
    sotw          : null,
    state         : null,
    url           : 'http://media.cardomain.com/bserver',
    vehicle       : null,
    year          : null
  },
  adGroups : [['top','frame1','expand','skin'],   // Default L++ associated creatives
              ['position3','bottom3']             // Default inverse L associated creatives
             ],
  adSrc      : function(associate_group) {
    var i,positions = [],specs = ATLASAds.specs;                                    
    var components = [],keywords = [],url;
    var rand = (''+Math.random()).slice(2,10);
    var adSize = {
		cptop160 : '160x600',
		cpbtf160 : '160x600'
    };
    
    function build_position_requests(actuals,associate_group) {
      var these,positions = [],groups = ATLASAds.adGroups;
      Array.prototype.has = function(elem) {
        for (var i=0; i<this.length; i++)
          if (this[i] == elem) return true;
        return false;
      }      
      function inGroup(pos) {
        for (var i=0; i<groups.length; i++) {
          if (groups[i].has(pos)) return true;
        }
        return false;
      }
      
      these = (groups[associate_group] || []).slice();  // make a copy of this group's positions
      if (associate_group == 0) {
        for (i=0; i<actuals.length; i++) {
          if (!inGroup(actuals[i])) these.push(actuals[i]);
        }
      }      
      for (var i=0,posIX=0; i<these.length; i++) {
        var specpos = these[i];
        if (actuals.has(specpos)) {
          positions[posIX] = specpos.replace(/^/,'AAMB_') + '/position=' + specpos;
          if (specpos in adSize) positions[posIX] += '/aamsz=' + adSize[specpos];
          posIX++;
        }
      }
      delete Array.prototype.has;
      return positions;
    }

    function specValue(spec) {
      return spec.replace(/^\s+|\s+$/,'').replace(/[^A-Za-z0-9_\.]/g,'_');
    }      
    for (var prop in specs) {
      switch(prop) {
        case 'group_tags':
          if (specs.group_tags) {
            var tags = [];
            for (var ti=0; ti<specs.group_tags.length; ti++) tags.push(specValue(specs.group_tags[ti]));
            components.push('group_tags=' + encodeURIComponent(tags.sort().join(',').toString()));
          }
          break;
        case 'positions':
          positions = build_position_requests(specs.positions,associate_group);
          break;
        case 'url':     
          break;
        default: 
          if (specs[prop]) components.push(prop + '=' + encodeURIComponent(specValue(specs[prop])));
      }
    }
    
    url = specs.url + "/AAMALL/acc_random=" + rand + "/pageid=" + rand +
          "/" + components.join('/');
    if (keywords.length) url += '/keyword=' + encodeURIComponent(keywords.join('$'));
    url += '/' + positions.join('/');
    return url;
  },
  request    : function(specArgs) {
    var specs = ATLASAds.specs;
    for (var prop in specs) {           
      if (prop in specArgs) specs[prop] = specArgs[prop];
      if (specs[prop] instanceof Array) { // ensure lowercase values
        for (var i=0,spec=specs[prop]; i<spec.length; i++) spec[i] = spec[i].toLowerCase();
      } else if (typeof specs[prop] == 'string') specs[prop] = specs[prop].toLowerCase();
    }
    specs.url = specs.url.replace(/\/*$/,'');
    if (specs.positions.length == 0 || specs.url.length == 0) return;   // missing inputs? then don't document.write
    specs.positions.sort();
    if (specs.group_tags) specs.group_tags.sort();
    if (ATLASAds.adGroups.length > 0) {
      for (i=0; i<ATLASAds.adGroups.length; i++) {
        document.write('<script type="text/javascript" src="' + ATLASAds.adSrc(i) + '"><\/script>');
      }
    } else {
      document.write('<script type="text/javascript" src="' + ATLASAds.adSrc(0) + '"><\/script>');
    }
  },
  setAssociateGroups : function() {
    ATLASAds.adGroups = [];
    for (var i=0; i<arguments.length; i++) {
      ATLASAds.adGroups.push(arguments[i]); 
    }
  },
  showAd     : function(name) {
    var adVar = window['AAMB_' + name];
    if (typeof adVar == 'string') {
      document.writeln('<div id="'+name+'_tmp">'+adVar+'<\/div>');
    }
  },   
  moveAd     : function(name) {
    var homeDiv = document.getElementById(name + '_spacer'),
        fromDiv = document.getElementById(name + '_tmp'),
        child,next,ad_temp_container;
    if (homeDiv && fromDiv) {
      ad_temp_container = fromDiv.parentNode;    // don't depend on id='ad_handling_container'
      for (child = fromDiv.firstChild; child; child = next) {
        next = child.nextSibling;
        homeDiv.appendChild(child);
      }
      fromDiv.parentNode.removeChild(fromDiv);
    }
    // Sometimes (multiply-nested document.writes?) elements break out of the _tmp div.
    // This catches those.
    if (ad_temp_container) {   
      for (child = ad_temp_container.firstChild; child; child = next) {
        next = child.nextSibling;
        if (child.nodeName.toUpperCase() == 'SCRIPT');  // skip moving extra SCRIPTS
        else if (/.*_tmp$/.test(child.id));             // or our own temp div
        else homeDiv.appendChild(child);
      }
    }
  }
};

