var Analytics = Class.create({
    subscribers : {},
    listeners : {},
    fromConfigListeners : [],
    seenMemoWithTag : {},
    isEnabled: false,
    enabledModules: new Array(),
    cm_map : {},
    cm_corrected_cat : {},
    localPath : '',
    macSkipCount : 0,
    prodCatData : {},
    uniqueEvents: [],
    swatchSkip : false,


    RPC_METHODS_ALLOWED: new Hash({
        "prodcat" : 1,
        "generic" : 1,
        "cart" : 1,
        "rpc.form" : 1,
        "search" : 1,
        "email.signup" : 1
    }),

    initialize: function(modules,enabled){
        this._addStaticListeners();
    },
    addPendingTags: function(newTags ){
        this.pendingTags = newTags;
        this.execTags();
        return this;
    },
    addElementEvents: function(newEvents){
        this.elementEvents = newEvents;
        
    },
    _addStaticListeners: function(){
        var self = this;
        document.observe("dom:loaded", function(){
            self.isEnabled = (typeof ANALYTICS_ENABLED != "undefined") ? ANALYTICS_ENABLED : false;
            self.enabledModules = (typeof ANALYTICS_MODULES != "undefined" ) ? ANALYTICS_MODULES : [];

            // CONVERSION EVENTS - If conversion events exist add handler as directed and form input for location
            self.jsEvents = (typeof CONVERSION_EVENTS != "undefined" ) ? CONVERSION_EVENTS : [];
            self.jsEvents = self.jsEvents.concat( (typeof JS_EVENTS != "undefined" ) ? JS_EVENTS : [] );
            self.jsPixelEvents = (typeof JS_PIXEL_EVENTS != "undefined" ) ? JS_PIXEL_EVENTS : new Object();

            if (Object.keys(self.jsPixelEvents).length > 0){
                Object.keys(self.jsPixelEvents).each(function(module){
                    self.jsPixelEvents[module].each(function(CEVENT){
                        self.jsEvents = self.jsEvents.concat( (typeof CEVENT != "undefined" ) ? CEVENT : [] );
                    });
                });
            }

            //console.log("addStaticListeners");
            //console.log(self.jsEvents);

            if (typeof self.jsEvents != "undefined"){
                //console.log(self.jsEvents);

                self.jsEventsWaited = [];

                self.jsEvents.each(function(CEVENT){
                    CEVENT.hookIds = [];  // allow for mapping one event to many elements
                    //console.log("event on ", CEVENT);
                    //Check for events to wait on, loading iframes, bv etc to be custom handled in static listeners
                    //if the ele is expected to exist on load, then the event handlers can be set up right away in addFrontendEvent

                    if (CEVENT.after){
                        self.jsEventsWaited.push(CEVENT);
                    }else{
                        //_addFrontendEvent: function(myElement,myEvent,tagBlocks)
                        self._addFrontendEvent(CEVENT);
                    }

                });

            }
            // console.log( "Analytics enabled: ", self.isEnabled );
            // console.log( "Analytics registered modules: ", self.enabledModules );

            self.localPath = document.location.pathname;

            // I loath this, but events fire user generated or not and something has to supress them on direct urls to SPP, for example

            if ( self.localPath.match("product") ){
                self.macSkipCount = 3; 
            }
            if (self.localPath.match("account") ){
                self.macSkipCount = 1;
            }
            if (self.localPath.match("looks") ){
                self.macSkipCount = 3;
            }
            if (self.localPath.match("artists")){
                self.macSkipCount = 1;
            }
            if (self.localPath.match("category")){
                self.macSkipCount = 3;
            }
            if (self.localPath.match("whats_new")){
                self.macSkipCount = 2;
            }

            //if (typeof site != "undefined"){
            //    if (typeof site.globalnav != "undefined"){
            //        self.createMap();
            //    }
            //}
        });


        // Mac special start
        document.observe("panelnav:show", function(event) {

            var open_data = event.memo.msg;
            //console.log("brand.coremetrics.panelNav.track: show / ",open_data);

            if (open_data.type === "panel"){
                //console.log("panel show");
                // if (typeof open_data.sectionId != "undefined"){

                self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[open_data.sectionId +" : "+ open_data.displayName  ,null,open_data.itemId,null,null],"tag":"cmCreatePageviewTag"}]}});

                var elementCat = "NAV";
                if (open_data.parentId !== 'globalnav_container'){
                    elementCat = elementCat + " : " + open_data.sectionId;
                }
                self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[open_data.displayName,elementCat,null,null,null,null],"tag":"cmCreatePageElementTag"}]}});

            } else if (open_data.type === "accordion") {
                //console.log("accordion show");
            }
        });

    document.observe("accordion:open", function(event) {
        //console.log(event);

        if ( self.macSkipCount ){
          self.macSkipCount--;
          return;
        }
        var open_data = event.memo.msg;
        //console.log("brand.coremetrics.Accordion.track: open / ", open_data);
        var parentCat =''
        var parentCatName = '';
        var curCat = '';
        var prefix = 'MPP : ';
        if (open_data.parentId === 'globalnav_container'){
            prefix = '';
        }else{
            if ( open_data.parentId.match("CAT[0-9]+") ) {
                parentCat = open_data.parentId.match("CAT[0-9]+")[0];
                parentCatName = self.cm_map[parentCat];
            }
            else if (open_data.parentId.match("psubnav_") ) {
                // psubnav's don't get parentId's, instead, they get psubnav_{parent.displayName}
                parentCatName = open_data.parentId;
                parentCatName = parentCatName.replace("psubnav_","");
            }
            curCat = open_data.id.match("CAT[0-9]+")

        }
        // remove Shop Products and Makeup Artistry because they are special cases
        if (open_data.displayName != "Nos Produits" && open_data.displayName != "L'Art Du Maquillage"){
            if (open_data.displayName != "Shop Products" && open_data.displayName != "Makeup Artistry"){
                self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[prefix + parentCatName + " : " + open_data.displayName,null,curCat,null,null],"tag":"cmCreatePageviewTag"}]}});
            }
        }

        var elementCat = "NAV";
        if (open_data.parentId !== 'globalnav_container'){
            elementCat = elementCat + " : " + parentCatName;
        }

        self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[open_data.displayName,elementCat,null,null,null],"tag":"cmCreatePageElementTag"}]}});
    });


    // The below might be removable, but just commented out the tag line for now. 
    // SPECIAL HOOK for Mac catalog.tmpl work around, also note, page_data doesn't have any English names so we have to use results from the RPC not in page_data, saving here.
    document.observe("panel:prodcat", function(event){


       // Save for possible later use 
           self.prodCatData = event.memo.msg.data;
       if ( self.macSkipCount ){
          self.macSkipCount--;
          return;
        }
       var prodcatRequest = event.memo.msg.request;
       var thisCat = '';
       if (self.cm_corrected_cat[prodcatRequest.itemId] != "undefined"){
           thisCat = self.cm_corrected_cat[prodcatRequest.itemId];
           //console.log("corrected cat ",thisCat);
       }else{
           thisCat = prodcatRequest.itemId;
       } 
       //catID = page_data.catalog.collection.match("CAT[0-9]*"); 
       //self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":["products : "+ prodcatRequest.parent.displayName  ,null,prodcatRequest.itemId,null,null],"tag":"cmCreatePageviewTag"}]}});
    
    });



    // this is a lot more specific to when we need a product view tag on a swatch click vs the generic swatch:click event. 
    document.observe("productmessage:cartadd/show", function(event){
       var cur_cat = event.memo.msg.path.match("CAT[0-9]*");
       var cur_prod = event.memo.msg.path.match("PROD([0-9]*)")[0];
       var pdcatalog = page_data.catalog;
       var productName = '';
       if (self.swatchSkip){
           return;
       }
            if (typeof(pdcatalog) != "undefined") {
                if (typeof(pdcatalog.mpp) != "undefined") {
                    if (typeof pdcatalog.mpp.products != "undefined"){
                        for (var i=0; i < pdcatalog.mpp.products.length; i++){
                            if (pdcatalog.mpp.products[i].category_id.match(cur_cat) && pdcatalog.mpp.products[i].product_id.match(cur_prod) ){
                                //console.log("GOT NAME ",pdcatalog.mpp.products[i].cm_name, cur_cat, pdcatalog.mpp.products[i].category_id); 
                                productName = pdcatalog.mpp.products[i].cm_name;
                            } 
                        }    
                    }else{
                        Object.keys(pdcatalog.mpp).each(function(CATEGORY){    
                           var CAT = pdcatalog.mpp[CATEGORY];
                           if (typeof CAT.products != "undefined"){
                               for (var i=0; i < CAT.products.length; i++){
                                   if (CAT.products[i].category_id.match(cur_cat) && CAT.products[i].product_id.match(cur_prod) ){
                                       //console.log("GOT NAME ",CAT.products[i].cm_name);
                                       if (typeof CAT.products != "undefined"){
                                          productName = CAT.products[i].cm_name;
                                       }
                                   }
                               }
                           }
                        });
                    }
                }

            }

           self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[cur_prod,productName,cur_cat ,null,null,null],"tag":"cmCreateProductviewTag"}]}});
       

   });
   
 

   //Search hook for frontend and soon Endeca
   document.observe("search:results", function(event){
    var res = event.memo.msg;
    self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[res.pageid,res.keywords,res.cat,'"' + res.count +'"',null],"tag":"cmCreatePageviewTag"}]}});
  });


     // BV loaded and ready this is just a place to handle the event, tags come from the backend config.
     document.observe("bv:loaded", function(){
         //console.log("BV IS LOADED",self.jsEventsWaited);
         self.jsEventsWaited.each(function(EVENT){
             if (EVENT.after && EVENT.after == 'bv:loaded'){
                 self._addFrontendEvent(EVENT);
             }
         });
     });

     document.observe("bv:created", function(){
         //console.log("BV IS LOADED",self.jsEventsWaited);
         self.jsEventsWaited.each(function(EVENT){
             if (EVENT.after && EVENT.after == 'bv:created'){
                 self._addFrontendEvent(EVENT);
             }
         });
     });

     // site.globalnav.config has loaded event
     document.observe("sitenav:loaded", function(args){
         //console.log("analytics: SITE NAV loaded ",args);
         self.createMap(args.memo.items);
     });


        // our RPC hook
        document.observe('RPC:RESULT', function(obj){
     
            var rpcRequestArray, rpcResponseArray;
            var requestMethod, requestId;
            if (typeof obj.memo.msg.request != "undefined") {
                rpcRequestArray = (obj.memo.msg.request.parameters.JSONRPC != null) ?
                    obj.memo.msg.request.parameters.JSONRPC.evalJSON() :
                    null;

                if (rpcRequestArray) {
                    rpcResponseArray = obj.memo.msg.responseText.evalJSON();
                    if (rpcResponseArray) {
                        rpcRequestArray.each(function(rpcRequest){
                            requestMethod = rpcRequest.method;
                            requestId = rpcRequest.id;
                            // console.log("Analytics handling RPC request:  ", requestMethod, " with id: ", requestId);

                            // We can do special handlers for requests here or filter out non handled requests... 
                            if (!self.RPC_METHODS_ALLOWED.get(requestMethod)) {
                                 //console.log("Analytics skipped ", requestMethod);
                            } else {
                                // Make sure we have the response for this request (id's must match).
                                var myRpcResponse = rpcResponseArray.find(function(rpcResponse){
                                    return rpcResponse.id == requestId
                                });
                                if (myRpcResponse && myRpcResponse.result != null) {
                                    //console.log("Analytics will handle ", myRpcResponse.result.data.Analytics);
                                    var newTags = myRpcResponse.result.data.Analytics;
                                    self.addPendingTags(newTags);
                                }
                            }
                        });
                    }
                }
            }
        });
   

       //Page data already exists hook
        document.observe('PAGEDATA:RESULT', function(obj){
            //console.log("GOT PAGE DATA ",obj);
            if (typeof obj.memo != "undefined"){
                var catalog_path = obj.memo.msg;
                var isLooks=false;
                var localPath=document.location.pathname;

                 if (localPath.match("looks") ){
                     catalog_path="catalog.mpp";
                     isLooks=true;
                 }
                 if (localPath.match("newsworthy") ){
                     return;
                 }
                if (typeof eval ('page_data.' + catalog_path) != "undefined"){
                    if (prodList =  eval ('page_data.' + catalog_path ) ){
                            //console.log("page data from products ", prodList);
                            if (obj.memo.msg.match("mpp") ){
                              for (var i=0; i < prodList.length; i++){
                                if( prodList[i].shaded == 0){
                                 //console.log("pending tags ",prodList[i].cm_name,prodList[i].category_id,prodList[i].product_id,prodList[i].shaded );
                                 self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[prodList[i].product_id,prodList[i].cm_name,prodList[i].category_id ,null,null,null],"tag":"cmCreateProductviewTag"}]}});
                                }
                              }
                            }
                            if ( catalog_path.match("spp") ){
                                //console.log("pending tags SPP");
                                //console.log("pending tags ",prodList.cm_name,prodList.category_id,prodList.product_id,prodList.shaded,prodList.cross_sell);
                                self.swatchSkip = true;
                                self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[prodList.product_id,prodList.cm_name,prodList.category_id ,null,null,null],"tag":"cmCreateProductviewTag"}]}});
                                if (prodList.cross_sell.length > 0){
                                    for (var i=0; i < prodList.cross_sell.length; i++){
                                        if (prodList.cross_sell[i].shaded==0){
                                             p = prodList.cross_sell[i];
                                             //console.log("pending tags cross sell ",p.cm_name,p.category_id,p.product_id);
                                            self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[p.product_id,p.cm_name,p.category_id ,null,null,null],"tag":"cmCreateProductviewTag"}]}});

                                        }
                                    }
                                }
                            }
                            if ( isLooks==true ){ // more special cases for some reason
                                //console.log("pending tags Looks");
                                Object.keys(prodList).each(function(CATEGORY){
                                    var CAT = prodList[CATEGORY];
                                    if (typeof CAT != "undefined"){
                                        for (var i=0; i < CAT.products.length; i++){
                                            if (typeof CAT.products[i] != "undefined"){
                                                if( CAT.products[i].shaded == 0){
                                                    //console.log("pending tags looks ",CAT.products[i].cm_name,CAT.products[i].category_id,CAT.products[i].product_id,CAT.products[i].shaded );
                                                    self.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CAT.products[i].product_id,CAT.products[i].cm_name,CAT.products[i].category_id ,null,null,null],"tag":"cmCreateProductviewTag"}]}});
                                                }
                                            }
                                        }
                                    }


                                });
                            }
                    }else{
                        //console.log("NO TAG DATA FROM PAGE DATA - catalog_path");
                    }
                }else{
                    //console.log("NO TAG DATA FROM PAGE DATA - catalog_path doesn't exist");
                }
            }else{
                //console.log("NO TAG DATA FROM PAGE DATA - obj.memo undef");
            }

        });
     }, 


    addDynamicListener: function(taggingModule, myEvent, TagBlocks){
        var self = this;
        var id = "default";
        TagBlocks.each(function(tagBlock){
            if (typeof tagBlock.memo != "undefined") {
                id = tagBlock.memo;
            }
            if (!self.subscribers[id]) { self.subscribers[id] = {}; }
            if (!self.subscribers[id][taggingModule]) { self.subscribers[id][taggingModule] = {}; };
            if (!self.subscribers[id][taggingModule][myEvent]) {
                self.subscribers[id][taggingModule][myEvent] = new Array();
            } else {
                 //console.log( "Event is defined ", self.subscribers[id][taggingModule][myEvent] );
            }

            if (!self.seenMemoWithTag[id]) { self.seenMemoWithTag[id] = {}; }
            if (!self.seenMemoWithTag[id][tagBlock.tag]) {
                self.seenMemoWithTag[id][tagBlock.tag] = 1;
                self.subscribers[id][taggingModule][myEvent].push(tagBlock);
                //console.log( "pushed Event for: id: ", id, " taggingModule: ", taggingModule, " event: ", myEvent, " -> ", self.subscribers[id][taggingModule][myEvent] );
            }

        });

        // Attach the listener for this event type.
        if (!self.listeners[myEvent]) {
            self.listeners[myEvent] = 1;
            //Event.observe(window, myEvent, function(evt){
            document.observe(myEvent, function(evt){
                //console.log("running window event: ", myEvent, " with memo: ", evt.memo);

                var myId = evt.memo;
                self.enabledModules.each(function(taggingModule){
                     //console.log("for tagging module: ", taggingModule);
                    if (typeof self.subscribers[myId][taggingModule] != "undefined"){
                       if (self.subscribers[myId][taggingModule][myEvent]) {
                             //self.execEventTagBlocks( self.subscribers[myId][taggingModule][myEvent] );
                          if ( taggingModule.match("CoreMetrics") ) {
                              self.execEventTagBlocks( self.subscribers[myId][taggingModule][myEvent] );
                          }else{
                              self.execImageBlocks(  self.subscribers[myId][taggingModule][myEvent], evt );
                          }

                       }
                    }
                });
            });
        }
    },
    execTags: function (){
        var self = this;
        if (typeof self.pendingTags == "object") {
            Object.keys(self.pendingTags).each(function(taggingModule){
                if (typeof taggingModule != "object" && self.pendingTags[taggingModule] == 'notag') {
                        return;
                }
                Object.keys(self.pendingTags[taggingModule]).each(function(myEvent){
                    // console.log("Analytics: module / event ", taggingModule, myEvent);
			        if (myEvent != 'dom:loaded'){
                        // register this event with our collection of listeners.
                        self.addDynamicListener(taggingModule, myEvent, self.pendingTags[taggingModule][myEvent]);
                        // and then execute it
                        //self.execEventTagBlocks( self.pendingTags[taggingModule][myEvent] );
                    } else {
                        // incoming tagging events under the 'dom:loaded' label can be executed straightaway.
                        //self.execEventTagBlocks( self.pendingTags[taggingModule][myEvent] );
                        if ( taggingModule.match("CoreMetrics") ) {
                            self.execEventTagBlocks( self.pendingTags[taggingModule][myEvent] );
                        }else{
                            self.execImageBlocks( self.pendingTags[taggingModule][myEvent], null );
                        }
                    } 
                }); 
            });
        }
    },
    execEventTagBlocks: function(tagBlocks){
        tagBlocks.each(function(tagBlock){
            if (!tagBlock.params || !tagBlock.tag) { return; }
                 console.log( "Analytics.execEventTagBlocks about to execute tag: ", tagBlock.tag, " with params: ", tagBlock.params );
            if (typeof window[tagBlock.tag] == "undefined") {
                 //console.log( "The Tagging Module function is not found: ", tagBlock.tag );
                return;
            }
            window[tagBlock.tag].apply(this, tagBlock.params);
        });
    },

    execImageBlocks: function(tagBlocks, evt){

        // If we were called because of a click on an href, save the url, stop the browser from following,
        // and then move to the url after the images have loaded. No url or same page anchor tags?
        // Then we only load the images.
        var href = null;
        Event.extend(evt);
        if (typeof evt.target.href != "undefined") {

            href = evt.target.href;

            var ele = Event.element(evt);
            var elehref = ele ? ele.getAttribute("href") : '';
            if ( elehref.match(/^#/) ) {
                // Ignore links to page anchors
                href = null;
            }

            if (href) {
                //console.log("Stopping browser from following link ", href);
                //evt.preventDefault();
                Event.stop(evt);
            }
        }

        // these often have a rnd number, gen that here to make sure it isn't used over and over as a global
        var axel = Math.random() + "";
        var num = axel * 1000000000000000000;

        var tagImages = new Array();

        tagBlocks.each(function(tagBlock){

            // src => 'http://foo/bar'
            // src => [ 'http://foo', 'http://bar' ]
            var imgSources = (typeof tagBlock.src == "string") ? [ tagBlock.src ] : tagBlock.src;

            imgSources.each(function(src){
                var img = document.createElement('img');

                // onload and friends must be set before setting img.src = ...
                // FF/others will load when you img.src = ... but won't set
                // the onload method until this block finishes
                // Also be weary of IE7.. Each iteration of an animated gif
                // will trigger an onload
                img.hasCompleted = false;
                img.onload = function() { this.hasCompleted = true; };
                img.onerror = function() { this.hasCompleted = true; };
                img.onabort = function() { this.hasCompleted = true; };

                tagImages.push(img);

                src = src.replace("rndnum",num);

                console.log( "Analytics.execImageBlocks about to load image: ", src);

                img.src = src;
            });
        });

        if (href != null) {
            var testAttempts = 0;
            function testImg(){
                //console.log("Analytics.execImageBlocks checking completed");
                testAttempts++;
                var numCompleted = 0;
                tagImages.each(function(img){
                    //console.log("Checking ", img.src, img);
                    if (img.hasCompleted || (img.complete != null && img.complete == true)) {
                        numCompleted++;
                    }
                });
                if ((numCompleted == tagImages.length) || (testAttempts >= 3)) {
                    //console.log("Completed.");
                    if (href != null) {
                        //console.log("Moving browser to ", href);
                        window.location = href;
                    }
                    return;
                }
                setTimeout(testImg, 500);
            }
            setTimeout(testImg, 500);
        }
    },


     _addFrontendEvent: function(EVENT){
        var self = this;

        if ( $(EVENT.domID) == null && EVENT.event != "dom:loaded" ){
            //console.log("CM ELEMENT does not EXIST! ",EVENT.domID);
            //return;
        }
        if (EVENT.event == "dom:loaded"){
            self.execTagsbyType(EVENT, null);
        }else{
            if (EVENT.domID || (EVENT.attachAttr && EVENT.attachValue) ){
               self._attachFrontendEvent(EVENT);
            }
        }
    },

    _attachFrontendEvent: function(EVENT){
        var self = this;
            // EVENT.attachAttr && EVENT.attachValue are required unless EVENT.domID is specified(for legacy cases with email signups)

            if (EVENT.domID){
                 EVENT.attachAttr = 'id';
                 EVENT.attachValue = EVENT.domID;
            }
            if (typeof EVENT.attachTag == "undefined"){
                 EVENT.attachTag = '';
            }
            if (EVENT.attachAttr && EVENT.attachValue){
               //console.log ( "got ",EVENT.attachTag,EVENT.attachAttr,EVENT.attachValue,EVENT.event);
               var theseListeners = [];
               $$(''+ EVENT.attachTag + '[' + EVENT.attachAttr + '="' + EVENT.attachValue + '"]').each(function (ele){
                    EVENT.hookIds.push( $(ele).identify() ); // if id doesn't exist give it one to use for matching in event handlers
                    self.fromConfigListeners.push(ele); // keep a full current list for ref
                    theseListeners.push(ele); // but don't dupilicate events
               });

                 theseListeners.each( function(ele){
                       //console.log("DOM ID IS ",EVENT.domID,EVENT,ele);
                     ele.observe(EVENT.event, function(evt){
                        //console.log("running event ",evt);
                        if (self.uniqueEvents.indexOf(ele) != -1){
                            return;
                        }
                        self.uniqueEvents.push(ele);

                        // which events match in the current list?
                        var cevents;
                        self.jsEvents.each(function(CEVENT){
                             CEVENT.hookIds.each(function(hooks){
                                var nodecheck = null;
                                if (hooks == evt.target.parentNode.id){
                                   nodecheck = evt.target.parentNode.id;
                                }
                                if (hooks == evt.target.id){
                                   nodecheck = evt.target.id;
                                }
                                if (nodecheck){
                                    cevents = CEVENT;
                                    //console.log("HOOK MATCHED ",hooks,CEVENT);
                                    // now we know the event and have the data, exec the tag according to type
                                    self.execTagsbyType(CEVENT, evt);
                                }
                             });
                        });
                        ele.stopObserving();
                     });
               });
            }
     },

    // tags specificly connected to user actions and tags more closely connected to frontend events vs backend data, like prodcat
     /*
         cmCreatePageElementTag(elementID, elementCategory,attributes)
         cmCreateManualPageviewTag(pageID, categoryID,DestinationURL,ReferringURL)
         cmCreateManualLinkClickTag(href,name,pageID)
         cmCreateManualImpressionTag(pageID, trackSP, trackRE)
         cmCreateErrorTag(pageID, categoryID)
     */
    execTagsbyType: function(CEVENT, evt){

        // now config can use any JS var as param value.
        Object.keys(CEVENT).each(function(param){
                if ( param.match("_") ){
                    //console.log("match eval type param");
                    //console.log ( CEVENT[param]  );
                    newParam = param.replace(/_/,'');
                    CEVENT[newParam] = eval( CEVENT[param] );
                }
        });

        if (CEVENT.type == 'conversion_event'){
            if (CEVENT.points < 1){
                CEVENT.points = '"0"';
            }
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.eventID, CEVENT.actionType, CEVENT.cat, CEVENT.points,CEVENT.attributes],"tag":"cmCreateConversionEventTag"}]}});
        }
        if (CEVENT.type == 'element'){
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.elementID,CEVENT.elementCategory,CEVENT.attributes],"tag":"cmCreatePageElementTag"}]}});
        }
        if (CEVENT.type == 'mpageview'){
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.pageID,CEVENT.categoryID,CEVENT.DestinationURL,CEVENT.ReferringURL],"tag":"cmCreateManualPageviewTag"}]}});
        }
        if (CEVENT.type == 'mlinkclick'){
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.href,CEVENT.name,CEVENT.pageID],"tag":"cmCreateManualLinkClickTag"}]}});
        }
        if (CEVENT.type == 'mimpression'){
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.pageID,CEVENT.trackSP,CEVENT.trackRE],"tag":"cmCreateManualImpressionTag"}]}});
        }
        if (CEVENT.type == 'error'){
            this.addPendingTags({"CoreMetrics":{"dom:loaded":[{"params":[CEVENT.pageID,CEVENT.categoryID],"tag":"cmCreateErrorTag"}]}});
        }
        if (CEVENT.type == 'img'){
           //console.log("IMG tracker",CEVENT);
           this.execImageBlocks([CEVENT], evt);
        }

    },


    // Possible special funtions for front end (reserved for future use)
    onDivShow: function() {},
    onFrameUpdate: function() {},
    onJsRedirect: function() {},


// More just for Mac, but the createMap func itself or something like it could become more standard for Navs.
createMap: function(args) {
    //console.log("MAP BUILD");

    //var sections = site.globalnav.config.items;
    var sections = args;

    for (x in sections) {
        for (y in sections[x]){
            if (y === "items"){
                var items = sections[x].items;
                for (var element = 0; element < items.length; element++){
                    if (items[element] != null){
                        if (typeof items[element] != "undefined" && typeof(items[element].id)  != "undefined" && typeof(items[element].cmcat) != "undefined"){
                            this.cm_map[items[element].id] = items[element].name;
                        }
                        if ( !(items[element].id.match("CAT[0-9]+")) ){
                            this.cm_corrected_cat[items[element].id] = items[element].cmcat;
                        }
                    }
                 }
             }else{
                 if (typeof(sections[x].id)  != "undefined" && typeof(sections[x].cmcat) != "undefined"){
                     if ( !(sections[x].id.match("CAT[0-9]+")) ){
                         this.cm_corrected_cat[sections[x].id] = sections[x].cmcat;
                     }else{
                         this.cm_map[sections[x].id] = sections[x].name;
                     }
                 }
            }
       }
    }
}


});
Analytics = new Analytics();


