/*jslint evil: true, regexp: false */
/*
 * All java script logic for the application.
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 */

var app = (function(jQuery){

     if (!jQuery) {
          alert("jQuery is not loaded yet!");
          return null;
     }
     
     // Global dw private data goes here     

     // dw scope public
     return {
          URLs               : {}, // holds dw specific urls, check htmlhead.isml for some examples
          resources          : {},  // resource strings used in js
          constants          : {}, // platform constants, initialized in htmlhead.isml
          containerId          : "content",
          ProductCache     : null,  // app.Product object ref
          currencyCodes     : {}, // holds currency code/symbol for the site
          isInitialLoad   : true,
          productlazyload : null,

          dialogSettings: {
                    autoOpen: false,
                    buttons: {},
                    modal: true,
                    overlay: {
                        opacity: 0.9,
                         background: "#666666"
                    },
                   height: 530,
                   width: 800,
                   title: '',
                   // show: "slow", This is causing dialog to break in jquery 1.3.2 rel, show: "slide" works but not desired
                   hide: "normal",
                   resizable: false,
                   bgiframe: false
          },

          // default tooltip settings
          tooltipSettings: {
                    delay: 0,
                    showURL: false,
                    extraClass: "",
                    top: 15,
                    left: -100
          },

          // global form validator settings
          validatorSettings: {
               errorClass : 'error_message',
               errorElement: 'span',
               
               
               onfocusout: function(element) {
                    if ( this.submitted.hasOwnProperty(element.name) || element === this.lastElement ) {
                         this.element(element);
                    }
               },
               onkeyup: false,
              onsubmit: function(element) {
                    if ( !this.checkable(element) ) {
                         this.element(element);
                    }
               }
          },

          // app initializations called from jQuery(document).ready at the end of the file
          init: function() {
               // register initializations here

               // micicart object initialization
               app.minicart.init();
               
               // miniwishlist object initialization
               app.miniwishlist.init()
               
               // initialize form validator customizations
               app.validator();

               // extract hidden data and turn them into jQuery data objects
               app.hiddenData();
               
               // renders horizontal/vertical carousels for product slots
               jQuery('#horicarousel').jcarousel({
                  scroll: 1,
                  // Add call to Demandware Javascript function for Active Merchandising
                  itemVisibleInCallback: app.captureCarouselRecommendations
              });

              jQuery('#vertcarousel').jcarousel({
                  scroll: 1,
                    vertical: true,
                  // Add call to Demandware Javascript function for Active Merchandising
                  itemVisibleInCallback: app.captureCarouselRecommendations
              });     
              
              // attach click handler to print window buttons/links.
              jQuery(".printwindow").click(function(){
                   window.print();
                   return false;
              });     
          },
     
          // sub namespace app.ajax.* contains application specific ajax components
          ajax: {
               Success: "success",
               currentRequests: {}, // request cache

               // ajax request to get json response
               // @param - reqName - String - name of the request
               // @param - async - boolean - asynchronous or not
               // @param - url - String - uri for the request
               // @param - data - name/value pair data request
               // @param - callback - function - callback function to be called
               getJson: function(options) {
                    var thisAjax = this;

                    // do not bother if the request is already in progress
                    // and let go null reqName
                    if (!options.reqName || !this.currentRequests[options.reqName]) {
                         this.currentRequests[options.reqName] = true;
                         if(options.async === "undefined") { 
                              options.async = true;
                         }
                         // make the server call
                         jQuery.ajax({
                              contentType: "application/json; charset=utf-8",
                              dataType: "json",
                              url          : options.url,
                              cache     : true,
                              async     : options.async,
                              data     : options.data,

                              success: function(response, textStatus) {
                                   thisAjax.currentRequests[options.reqName] = false;
                                   
                                   if (!response || !response.Success) {
                                        return;
                                   }
                                   
                                   if (options.hasOwnProperty('callback') && options.callback ) { 
                                        options.callback(response, textStatus);
                                   }
                              },

                              error: function(request, textStatus, error) {
                                   if (textStatus === "parsererror") {                                        
                                        alert('bad response, parser error='+request+", options.url="+options.url + " error " + error);
                                   }
                                   
                                   options.callback({Success: false, data:{}});
                              }
                         });
                    }
               },


               // ajax request to load html response in a given container
               // @param - reqName - String - name of the request
               // @param - url - String - uri for the request
               // @param - data - name/value pair data request
               // @param - callback - function - callback function to be called
               // @param - selector - string - id of the container div/span (#mycontainer) - it must start with '#'
               load: function(options) {

                    var thisAjax = this;

                    // do not bother if the request is already in progress
                    // and let go null reqname
                    if (!options.reqName || !this.currentRequests[options.reqName]) {
                         this.currentRequests[options.reqName] = true;
                         // make the server call
                         var newOptions = {
                              dataType: "html",
                              url          : options.url,
                              cache     : true,
                              data     : options.data,

                              success: function(response, textStatus) {
                                   thisAjax.currentRequests[options.reqName] = false;
                                   
                                   if (options.selector) {
                                        jQuery(options.selector).html(response);
                                   }

                                   if (options.hasOwnProperty('callback')){ 
                                       options.callback(response, textStatus);
                                   }
                              },

                              error: function(request, textStatus, error) {
                                   if (textStatus === "parsererror") {                                        
                                        alert('bad response, parser error');
                                   }

                                   options.callback(null, textStatus);
                              }
                         };
                         if ( options.type ) {                               
                              newOptions.type = options.type;
                         }
                         jQuery.ajax( newOptions );
                    }
               }
          },

          // loads a product into a given container div
          // params
          //           containerId - id of the container div, if empty then global app.containerId is used
          //          source - source string e.g. search, cart etc.
          //          label - label for the add to cart button, default is Add to Cart
          //          url - url to get the product
          //          id - id of the product to get, is optional only used when url is empty
          getProduct: function(options) { // id, source, start
               var cId           = options.containerId || app.containerId;
               var source           = options.source || "";
               var a2cBtnLabel = options.label || null;
               var a2cBtnLabelSelector = options.labelSelector || ".addtocart_button:last";
               
               

               // show small loading image
               jQuery("#"+cId).html(app.showProgress("productloader"));

               var productUrl = options.url ? options.url : app.util.appendParamToURL(app.URLs.getProductUrl, "pid", options.id);
                              
               productUrl = app.util.appendParamToURL(productUrl, "source", source);

               app.ajax.load({selector: "#"+cId, url: productUrl, callback: function(responseText, textStatus){
                    if(options.hasOwnProperty('callback')) {
                         options.callback();
                    }
                    
                    // update the Add to cart button label if one provided
                    if (a2cBtnLabel !== null) { 
                         jQuery("#"+cId+" "+ a2cBtnLabelSelector).html(a2cBtnLabel);
                    }
               }});
          },

          // sub name space app.minicart.* provides functionality around the mini cart
          minicart: {
               state : 0, // flag, whether cart is open or not
               url   : '',  // during page loading, the Demandware URL is stored here
               showCartUrl : '',
               addWishlistUrl : '',
               user : '',
               timer : null, // timer for automatic close of cart item view
               
               currentItemIndex: 0,
               maxItemIndex: 0,

               // initializations
               init: function() {
                    // reset all the existing event bindings
                    app.minicart.reset();

                    // bind click event to the cart total link at the top right corner
                    jQuery(".minicarttotal").live( "click", function(e){
                         
                         if (typeof(IS_PT_CHECKOUT) !== "undefined")
                         {
                              if (IS_PT_CHECKOUT){
                               return false;     
                              }
                         }
                         window.location.href = app.minicart.showCartUrl;
                         return false;
                    });
                    
                    jQuery("#minicart").live( "mouseenter", function(e) {
                         clearTimeout(app.minicart.timer);
                         app.minicart.timer = null;
                         app.minicart.slide(2000000);
                    }).live( "mouseleave", function(e) {
                         clearTimeout(app.minicart.timer);
                         app.minicart.timer = null;
                         // after a time out automatically close it
                         app.minicart.timer = setTimeout( 'app.minicart.close()', 150 );
                    });

                    // register close button event
                    jQuery('#minicartcontent #minicartclose').live( "click", function() {
                         app.minicart.close(0);
                    });
               },
               
               // returns a boolean if a minicart is visible/shown or hidden
               isShow: function() {
                    return jQuery('#minicartcontent').css('display') === 'none' ? false : true;
               },
               
               // reset minicart
               reset: function() {
                    //jQuery(".minicarttotal").unbind("click");
                    jQuery(".minicarttotal").unbind("mouseover");
                    jQuery(".minicarttotal").unbind("mouseout");
                    jQuery('#minicartcontent').unbind("mouseenter").unbind("mouseleave");
                    jQuery('#minicartcontent #minicartclose').unbind("click");
               },

               // shows the given content in the mini cart
               show: function(html) {
                    jQuery('#minicart').html(html);
                    // bind all the events
                    app.minicart.init();
                    
                    if(!(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown())){
                         app.minicart.slide(7000);
                    }
               },
               
               // slide down and show the contents of the mini cart
               slide: function(timeout) {
                    if(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown()) {
                         return;
                    }
                    if(app.suggest.hasFocus)
                    {
                         app.suggest.acSearchField.blur();
                    }
                    
                    if (!jQuery('#minicart a.linkminicart').hasClass("zero")) {
                    	jQuery('#minicart a.linkminicart').addClass('on');
                    }
                    
                    // show the item
                    jQuery("div.minicartitem").not('.showing').hide();
                    // setTimeout( 'jQuery("#minicartcontent").slideDown("fast")', 30 );
                    
                    // scroll to top
                    jQuery('body,html').scrollTo('0px', 500);
                    jQuery("#minicartcontent").slideDown("fast");
                    
                    clearTimeout(app.minicart.timer);
                    app.minicart.timer = null;
                         
                    // after a time out automatically close it
                    app.minicart.timer = setTimeout( 'app.minicart.close()', timeout );
               },
               // adds a wishlist to the mini cart 
               addWishlist: function(progressImageSrc, postdata, callback)
               {
                    var postData = postdata;
                    // get button reference
                    var addButtons = [];
                    // the button to update
                    var addButton = null;
                    // it is an array of buttons, but we need only one all
                    // other combinations are strange so far
                    if (addButtons.length === 1)     {addButton = addButtons[0];}
                    var previousImageSrc = null;
                    // show progress indicator
                    if (addButton !== null) {
                         previousImageSrc = addButton.src;
                         addButton.src = progressImageSrc;
                    }
                    
                    var handlerFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if(addButton !== null) {addButton.src = previousImageSrc; }
                         
                         // replace the content
                         
                         jQuery('#minicart').html(req);
                         
                         if(!(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown())){
                              app.minicart.slide(7000);
                         }
                         
                         if (callback) {
                              callback();
                         }
                    };
                    
                    // handles add to cart error
                    var errFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }                    
                    };

                    // closes a previous mini cart
                    app.minicart.close();
                    
                    document.body.style.cursor = "wait";

                    // add the product
                    jQuery.ajax({
                         type     : "POST",
                         url          : app.minicart.addWishlistUrl,
                         cache     : true,
                         data     : postdata,
                         success     : handlerFunc,
                         error     : errFunc
                    });
                    
               },
               // adds a product to the mini cart
               add: function(progressImageSrc, postdata, callback)
               {

                    // get button reference
                    var addButtons = [];

                    // the button to update
                    var addButton = null;
                    
                    // it is an array of buttons, but we need only one all
                    // other combinations are strange so far
                    if (addButtons.length === 1)     {
                         addButton = addButtons[0];
                    }

                    var previousImageSrc = null;

                    // show progress indicator
                    if (addButton !== null) {
                         previousImageSrc = addButton.src;
                         addButton.src = progressImageSrc;
                    }

                    // handles successful add to cart
                    var handlerFunc = function(req)     {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }
                         
                         // replace the content
                         
                         jQuery('#minicart').html(req);
                         

                         if (!(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown())) {
                              app.minicart.slide(7000);
                         }
                         
                         // log this add to cart event
                         // check for logged in
                         
                         if (app.minicart.user != "")
                         { 
                        	 _gaq.push(['_trackEvent','CartAdd',postdata.pid,app.minicart.user, 1] );
         					
                         }
                         else 
                         {
                        	 browseActivity.logPid('AC', postdata.pid);
                         }
                         
                         
                         if (callback) {
                              callback();
                         }
                    };

                    // handles add to cart error
                    var errFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }                    };

                    // closes a previous mini cart
                    app.minicart.close();
                    
                    document.body.style.cursor = "wait";

                    // add the product
                    jQuery.ajax({
                                        type     : "POST",
                                        url          : app.minicart.url,
                                        cache     : true,
                                        data     : postdata,
                                        success     : handlerFunc,
                                        error     : errFunc
                                   });
               },

               // closes the mini cart with given delay
               close: function(delay) {
                    if ( app.minicart.timer !== null || delay === 0) {
                         clearTimeout( app.minicart.timer );
                         app.minicart.timer = null;     
                         
                         jQuery('#minicart a.linkminicart').removeClass('on');
                         
                         app.minicart.currentItemIndex = 0;
                         jQuery('#minicartcontent').hide(); 
                         //jQuery('#minicartcontent').fadeOut(); // hide with "slide" causes to fire mouse enter/leave events sometimes infinitely thus changed it to fadeOut
                    }
               },

               // hook which can be replaced by individual pages/page types (e.g. cart)
               suppressSlideDown: function() {
                    return false;
               },
               
               // pages forth within the minicart items
               pageForth: function() {
                    if (app.minicart.currentItemIndex === app.minicart.maxItemIndex) {
                         app.minicart.showItem(0);
                    } else {
                         app.minicart.showItem(app.minicart.currentItemIndex + 1);
                    }
               },
               
               // pages back within the minicart items
               pageBack: function() {
                    if (app.minicart.currentItemIndex === 0) {
                         app.minicart.showItem(app.minicart.maxItemIndex);
                    } else {
                         app.minicart.showItem(app.minicart.currentItemIndex - 1);     
                    }
               },
               
               // helper function to show the minicart item with at given item index
               showItem: function(itemIndex) {
                    if(itemIndex < 0 || itemIndex > app.minicart.maxItemIndex) {
                         return;
                    }
                    
                    app.minicart.currentItemIndex = itemIndex;
                    jQuery("div.minicartitem").hide().removeClass('showing');
                    jQuery("div#minicartitem-" + itemIndex).show().addClass('showing');
                    jQuery("div#minicartcontent span.current").html(itemIndex + 1);
               }
          },
          
          // sub name space app.miniwishlist.* provides functionality around the mini wishlist
          miniwishlist: {
               state : 0, // flag, whether wishlist is open or not
               url   : '',  // during page loading, the Demandware URL is stored here
               showWishlistUrl : '',
               addWishlistUrl : '',
               timer : null, // timer for automatic close of cart item view
               
               currentItemIndex: 0,
               maxItemIndex: 0,

               // initializations
               init: function() {
                    // reset all the existing event bindings
                    app.miniwishlist.reset();

                    // bind click event to the cart total link at the top right corner
                    jQuery(".miniwishlisttotal").live( "click", function(e){
                         window.location.href = app.miniwishlist.showWishlistUrl;
                         return false;
                    });
                    
                    jQuery("#miniwishlist").live( "mouseenter", function(e) {
                         clearTimeout(app.miniwishlist.timer);
                         app.miniwishlist.timer = null;
                         app.miniwishlist.slide(2000000);
                    }).live( "mouseleave", function(e) {
                         clearTimeout(app.miniwishlist.timer);
                         app.miniwishlist.timer = null;
                         // after a time out automatically close it
                         app.miniwishlist.timer = setTimeout( 'app.miniwishlist.close()', 150 );
                    });
               },
               
               // returns a boolean if a miniwishlist is visible/shown or hidden
               isShow: function() {
                    return jQuery('#miniwishlistcontent').css('display') === 'none' ? false : true;
               },
               
               // reset miniwishlist
               reset: function() {
                    jQuery(".miniwishlisttotal").unbind("mouseover");
                    jQuery(".miniwishlisttotal").unbind("mouseout");
                    jQuery('#miniwishlistcontent').unbind("mouseenter").unbind("mouseleave");
               },

               // shows the given content in the mini wishlist
               show: function(html) {
                    jQuery('#miniwishlist').html(html);
                    // bind all the events
                    app.miniwishlist.init();
                    
                    if(!(app.miniwishlist.suppressSlideDown && app.miniwishlist.suppressSlideDown())){
                         app.miniwishlist.slide(7000);
                    }
               },
               
               // slide down and show the contents of the mini wishlist
               slide: function(timeout) {
                    if(app.miniwishlist.suppressSlideDown && app.miniwishlist.suppressSlideDown()) {
                         return;
                    }
                    if(app.suggest.hasFocus)
                    {
                         app.suggest.acSearchField.blur();
                    }
                    
                    if (!jQuery('#miniwishlist a.linkminicart').hasClass("zero")) {
                    	jQuery('#miniwishlist a.linkminicart').addClass('on');
                    }
                    
                    // show the item
                    jQuery("div.miniwishlistitem").not('.showing').hide();
                    jQuery("#miniwishlistcontent").slideDown("fast");
                    
                    clearTimeout(app.miniwishlist.timer);
                    app.miniwishlist.timer = null;
                         
                    // after a time out automatically close it
                    app.miniwishlist.timer = setTimeout( 'app.miniwishlist.close()', timeout );
               },
               // adds a wishlist to the mini cart 
               addWishlist: function(progressImageSrc, postdata, callback)
               {
                    var postData = postdata;
                    // get button reference
                    var addButtons = [];
                    // the button to update
                    var addButton = null;
                    // it is an array of buttons, but we need only one all
                    // other combinations are strange so far
                    if (addButtons.length === 1)     {addButton = addButtons[0];}
                    var previousImageSrc = null;
                    // show progress indicator
                    if (addButton !== null) {
                         previousImageSrc = addButton.src;
                         addButton.src = progressImageSrc;
                    }
                    
                    var handlerFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if(addButton !== null) {addButton.src = previousImageSrc; }
                         
                         // replace the content
                         
                         jQuery('#minicart').html(req);
                         
                         if(!(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown())){
                              app.minicart.slide(7000);
                         }
                         
                         if (callback) {
                              callback();
                         }
                    };
                    
                    // handles add to cart error
                    var errFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }                    
                    };

                    // closes a previous mini cart
                    app.minicart.close();
                    
                    document.body.style.cursor = "wait";

                    // add the product
                    jQuery.ajax({
                         type     : "POST",
                         url          : app.minicart.addWishlistUrl,
                         cache     : true,
                         data     : postdata,
                         success     : handlerFunc,
                         error     : errFunc
                    });
                    
               },
               // adds a product to the mini cart
               add: function(progressImageSrc, postdata, callback)
               {

                    // get button reference
                    var addButtons = [];

                    // the button to update
                    var addButton = null;
                    
                    // it is an array of buttons, but we need only one all
                    // other combinations are strange so far
                    if (addButtons.length === 1)     {
                         addButton = addButtons[0];
                    }

                    var previousImageSrc = null;

                    // show progress indicator
                    if (addButton !== null) {
                         previousImageSrc = addButton.src;
                         addButton.src = progressImageSrc;
                    }

                    // handles successful add to cart
                    var handlerFunc = function(req)     {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }
                         
                         // replace the content
                         
                         jQuery('#minicart').html(req);
                         

                         if (!(app.minicart.suppressSlideDown && app.minicart.suppressSlideDown())) {
                              app.minicart.slide(7000);
                         }
                         if (callback) {
                              callback();
                         }
                    };

                    // handles add to cart error
                    var errFunc = function(req) {
                         document.body.style.cursor = "default";
                         // hide progress indicator
                         if (addButton !== null) {
                              addButton.src = previousImageSrc;
                         }                    };

                    // closes a previous mini cart
                    app.minicart.close();
                    
                    document.body.style.cursor = "wait";

                    // add the product
                    jQuery.ajax({
                                        type     : "POST",
                                        url          : app.minicart.url,
                                        cache     : true,
                                        data     : postdata,
                                        success     : handlerFunc,
                                        error     : errFunc
                                   });
               },

               // closes the mini wishlist with given delay
               close: function(delay) {
                    if ( app.miniwishlist.timer !== null || delay === 0) {
                         clearTimeout( app.miniwishlist.timer );
                         app.miniwishlist.timer = null;     
                         
                         jQuery('#miniwishlist a.linkminicart').removeClass('on');
                         
                         app.miniwishlist.currentItemIndex = 0;
                         jQuery('#miniwishlistcontent').hide(); 
                    }
               },

               // hook which can be replaced by individual pages/page types (e.g. cart)
               suppressSlideDown: function() {
                    return false;
               },
               
               // pages forth within the miniwishlist items
               pageForth: function() {
                    if (app.miniwishlist.currentItemIndex === app.miniwishlist.maxItemIndex) {
                         app.miniwishlist.showItem(0);
                    } else {
                         app.miniwishlist.showItem(app.miniwishlist.currentItemIndex + 1);
                    }
               },
               
               // pages back within the miniwishlist items
               pageBack: function() {
                    if (app.miniwishlist.currentItemIndex === 0) {
                         app.miniwishlist.showItem(app.miniwishlist.maxItemIndex);
                    } else {
                         app.miniwishlist.showItem(app.miniwishlist.currentItemIndex - 1);     
                    }
               },
               
               // helper function to show the miniwishlist item with at given item index
               showItem: function(itemIndex) {
                    if(itemIndex < 0 || itemIndex > app.miniwishlist.maxItemIndex) {
                         return;
                    }
                    
                    app.miniwishlist.currentItemIndex = itemIndex;
                    jQuery("div.miniwishlistitem").hide().removeClass('showing');
                    jQuery("div#miniwishlistitem-" + itemIndex).show().addClass('showing');
                    jQuery("div#miniwishlistcontent span.current").html(itemIndex + 1);
               }
          },          

          // close quick view dialog if open and refresh the page
          refreshCart: function() {
               // refresh without posting
               location.replace(location.href);
          },

          createDialog: function(options) {
               jQuery('#'+options.id).dialog(jQuery.extend({}, app.dialogSettings, options.options));
               jQuery('#'+options.id).dialog(jQuery.extend({}, app.dialogSettings, options.options));
          },


          tooltip: function(options) {
               if ((options.id.charAt(0) !== '#') && (options.id.charAt(0) !== '.')) {
                    options.id = "#"+options.id;
               }
               jQuery(options.id).tooltip(jQuery.extend({}, app.tooltipSettings, options.options));
          },

          // renders a progress indicator on the page; this function can be used
          // to indicate an ongoing progress to the user; the optional parameter "className"
          // can be used to attach an additional CSS class to the container
          showProgress : function(className) {
               var clazz = "loading";
               if (className) { 
                    clazz += " " + className;
               }
               return jQuery("<div class=\"" + clazz + "\"/>").append(jQuery("<img/>").attr("src", app.URLs.loadingSmallImg));
          },
          // renders a progress indicator on the page; this function can be used
          // to indicate an ongoing progress to the user; the optional parameter "className"
          // can be used to attach an additional CSS class to the container
          showSearchProgress : function(className) {
               var clazz = "loading";
               if (className) { 
                    clazz += " " + className;
               }
               return jQuery("<div class=\"" + clazz + "\"/>").append(jQuery("<img/>").attr("src", app.URLs.loadingSearchImg));
          },

          /*
           *     Opens a new window with the provided url and dimension. Used
           *     for Scene7 and other situations.
           *
           *     @param url the url to open
           *     @param width the window width
           *     @param height the window height
           */
          openPopup: function( url, width, height ) {
               if (url !== null) {
                    if (width !== null && height !== null) {
                         window.open(url, "", "width=" + width +", height=" + height +", scrollbars=no, resizable=yes");
                    }
                    else {
                         window.open(url, "", "scrollbars=no, resizable=yes");
                    }
               }
          },


          validator: function() {
               // override default required field message
               jQuery.validator.messages.required = function($1, ele, $3) {
                    return 'Please Enter '+jQuery(ele).data("data");
               };

               // register form validator for form elements
               // except for those which are marked "suppress"
               jQuery.each(jQuery("form:not(.suppress)"), function() {
                    jQuery(this).validate(app.validatorSettings);
               });
          },

          // grab anything inside a hidden span and append it to its immediate previous sibling
          hiddenData : function() {               
               jQuery.each(jQuery(".hidden"), function() {                    
                    var hiddenStr = jQuery(this).html();
                    
                    if (hiddenStr === "") {
                         return;
                    }
                    
                    // see if its a json string
                    if (jQuery(this).hasClass("json")) {
                         // try to parse it as a json
                         try {
                              hiddenStr = window["eval"]("(" + hiddenStr + ")");
                         }
                         catch(e) {}                    
                    }
                    
                    jQuery(this).prev().data("data", hiddenStr);
                    
                    //jQuery(this).remove();
               });
          },

          // capture recommendation of each product when it becomes visible in the carousel
          captureCarouselRecommendations : function(c, li, index, state) {
               jQuery(li).find(".captureproductid").each(function() {
                    dw.ac.capture({id:this.innerHTML, type:dw.ac.EV_PRD_RECOMMENDATION});
               });
          },
          
          // sub namespace app.producttile.* contains utility functions for product tiles
          producttile : {
               // initializes all product tiles contained in the current page
               initAll: function() {

                    // tile hover
                    jQuery('#search .producttile').live('mouseenter mouseleave', function(event) {
                           if (event.type == 'mouseenter') {
                                   jQuery(this).addClass("productHover");
                                   
                                   if (!jQuery(this).hasClass('loaded')) {
                                        // preload full images from swatches
                                        jQuery(this).find('div.swatches').find('a.swatch').each(function(){
                                             // grab colorway info
                                             var imageData = jQuery.parseJSON(jQuery(this).attr("data"));
                                             // var thisImageUrl = jQuery(this).attr('rel');
                                             var thisImageUrl = imageData.imageURL;
                                             jQuery("#"+imageData.productID + "-productImage").children('div.preload').append('<img src="' + thisImageUrl + '" style="display: none;"/>');
                                        });
                                        jQuery(this).addClass('loaded');
                                   }
                                   
                           } else {
                                jQuery(this).removeClass("productHover");
                           }
                    });
                    
                    // handle swatch click
                    jQuery("#search .producttile .swatches a.swatch").live("click", function(event) {
                         // grab parent
                         var parentObj = jQuery(this).parents(".swatches");
                         var productImage = parentObj.prev('div.productImage');
                         // var thisImageUrl = jQuery(this).attr('rel');
                         var imageData = jQuery.parseJSON(jQuery(this).attr("data"));
                         var thisImageUrl = imageData.imageURL;
                         
                         bui.crossFadeProductImages(productImage.children('a').children('img.product'), thisImageUrl);
                         
                         var thisProductURL = jQuery(this).attr('href');

                         // set selected class
                         parentObj.find("a").removeClass("selected");
                         jQuery(this).addClass("selected");

                         // update name and href of variation
                         productImage.children('a').attr("href", thisProductURL);
                         parentObj.next('div.productName').children('h2').children('a').attr("href", thisProductURL);
                         
                         return false;
                    });

                    jQuery(".swatches a.view-swatches").live("click", function(event) {
                         jQuery(this).next('.hidden-swatches').fadeIn(100);
                         return false;
                    });

                    jQuery(".swatches div.hidden-swatches").live('mouseleave', function(event) {
                    	jQuery(this).fadeOut(100);
                    });
               }
          },
          // sub namespace app.dealer.* contains Dealer Locator 
          dealer : {
               // some constants
               startIndex : 0,
               index : 0,
               dealerCount : 0,
               totalDealers : 0,
               elementsThatFit : 1,
               elementWidth : 150, // this is the width of a local Dealer
               windowWidth : 150, // this is the width of the viewable area
               dealerWidgetWidth : 413 - 150,
               firstPassDone : false,
               offSet : 0,
               nextLinkVisible : true,
               url: null,
               
               // init function
               // wires up all the necessary event listeners
               init : function(options) {
                    // if there is a secondary dealer locator, do it here
                   if (typeof(options) !== "undefined")
                   {
                         // make this call where supported
                         if (jQuery(options.container).size() > 0) {
                              app.dealer.getDealers(options);
                         }
                   }
                   else 
                   {
                         // make this call where supported
                         if (jQuery('#footer-dealers').size() > 0) {
                              var options2 = { };
                              options2.container = '#footer-dealers';
                              app.dealer.getDealers(options2);
                       }
                   }
                    
                    
               },
               // get the dealers
               getDealers : function (options) {
                    var url = options.url || app.dealer.url;
                    var data = options.data || {};
                    
                    var container = options.container || '#footer-dealers' ;
                    // post the data and replace current content with response content
                      jQuery.ajax({
                       type: "POST",
                       url: url,
                       data: data,
                       dataType: "html",
                       success: function(data){
                                
                                jQuery(container).prepend(data);
                                app.dealer.bindEvents(options);
                                
                                if ( options.hasOwnProperty('callback') && options.callback ){
                                     options.callback(data);
                                }
                       },
                       failure: function(data) {
                            alert("Server connection failed!");
                       }
                    });
               },
               onBefore : function(curr, next, opts) {
                   var total = jQuery(this).parent().children().size();
                   var index = jQuery(this).parent().children().index(this);
                   jQuery(curr).parents('#dealer-window').next('.carousel-controls').find('li.pager').text(index+1 + ' of ' + total);
             	   jQuery('#footer-dealers #dealerPane').height(jQuery(next).height());
               },
               bindEvents : function (options) {
                    jQuery(options.container + ' #dealerPane').cycle({
                       fx: 'scrollHorz',  
                       speed:   500,
                       timeout: 0,
                       prev: options.container + ' #prev-dealer',
                       next: options.container + ' #next-dealer',
                       before: app.dealer.onBefore
                   });
                    app.dealer.isInitialLoad = false;
               }
          },
          // sub namespace app.util.* contains utility functions
          util : {
               // disables browser auto completion for the given element
               disableAutoComplete : function(elemId) {
                    jQuery("#"+elemId).attr("autocomplete", "off");
               },

               // trims a prefix from a given string, this can be used to trim
               // a certain prefix from DOM element IDs for further processing on the ID
               trimPrefix : function(str, prefix) {
                    return str.substring(prefix.length);
               },

               // appends the parameter with the given name and
               // value to the given url and returns the changed url
               // allows the name to be an object.  two variations:
               // 1  { 'param1', 'value1', 'param2', 'value2' }
               // 2  [ { name: 'param1', value: 'value1'}, {name: 'param2', value: 'value2' }]
               appendParamToURL : function(url, name, value) {
                    if ( typeof(name) === 'object' )
                    {
                         return url + '?' + jQuery.param( name );
                    }
                    
                    var c = "?";
                    if(url.indexOf(c) !== -1) {
                         c = "&";
                    }
                    return url + c + name + "=" + encodeURIComponent(value);
               },

               // dynamically loads a CSS file
               loadCSSFile : function(url) {
                    var elem = document.createElement("link");
                    elem.setAttribute("rel", "stylesheet");
                    elem.setAttribute("type", "text/css");
                    elem.setAttribute("href", url);

                    if(typeof(elem) !== "undefined") {
                         document.getElementsByTagName("head")[0].appendChild(elem);
                         app.util.loadedCSSFiles.push(url);
                    }
               },

               // array to keep track of the dynamically loaded CSS files
               loadedCSSFiles : [],

               // removes all dynamically loaded CSS files
               clearDynamicCSS : function() {
                     var i;
                    for(i=0; i<app.util.loadedCSSFiles.length; i++) {
                         app.util.unloadCSSFile(app.util.loadedCSSFiles[i]);
                    }
               },

               // dynamically unloads a CSS file
               unloadCSSFile : function(url) {
                    var candidates = document.getElementsByTagName("link");
                    var i;
                    for( i=candidates.length; i>=0; i--) {
                         if(candidates[i] && candidates[i].getAttribute("href") !== null && candidates[i].getAttribute("href").indexOf(url) !== -1) {
                              candidates[i].parentNode.removeChild(candidates[i]);
                         }
                    }
               },

               // checks if cookies are enabled
               cookiesEnabled : function() {
                    var currentCookie = document.cookie;
                    document.cookie = "Enabled=true";
                    var cookieValid = document.cookie;
                    var result = false;

                    if(cookieValid.indexOf("Enabled=true") !== -1) {
                         result = true;
                    }

                    document.cookie = currentCookie;
                    return result;
               },
               
               // changes the selection of the given form select to the given value
               changeFormSelection: function (selectElem, selectedValue) {
                    if(!selectElem){
                         return;
                    }
                    var options = selectElem.options;
                    var valu;
                    var txt;
                    var idx;
                    var i;
                    if(options.length > 0) {
                         // find index of value to select
                         idx = 0;
                         for(i=0; i<options.length; i++) {
                              if(options[i].value === selectedValue) {
                                   valu = options[i].value;
                                   txt =  options[i].text;
                                   idx = i; 
                                   break;
                              }
                         }
                         selectElem.selectedIndex = idx;
                         //alert(selectElem + '|' + txt + '|'+ valu + '|' + selectedValue + '|' + idx + '|' + jQuery(selectElem + "[value='"+valu+"']").val() + '|' + jQuery(selectElem + "[value='"+idx+"']").val());
                         if (jQuery(selectElem + "[value='"+idx+"']").val() === undefined)
                         { 
                              //alert('reset valu');
                              valu = idx; //jQuery(selectElem + "[value='"+idx+"']").index()
                         }
                         else 
                         { 
                              valu = jQuery(selectElem + "[value='"+idx+"']").val(); 

                         } 
                         //alert(valu);
                         jQuery(selectElem).selectmenu('value', valu);
                    }
               }
          },

          // sub namespace app.dialog.* provides convenient functions to handle dialogs
          // note, that this code relies on single dialog modals (multi dialog, e.g. modal in modal is not supported)
          dialog : {
               customOptions : {},
               // opens a dialog using the given url
               open : function(url, title, dialogClass, myOptions) {
                    // create the dialog container if not present already
                    if(jQuery("#dialogcontainer").length === 0) {
                         jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
                    }

                    // set a default title
                    title = title || "";
                    
                    //set a default class
                    dialogClass = dialogClass || "";

                    // finally load the dialog, set the dialog title
                    var newOptions = {
                         selector: "#dialogcontainer",
                         url: url,
                         callback: function() {
                              app.dialog.checkOpen( myOptions );
                              app.dialog.setTitle(title);
                              app.dialog.setClass(dialogClass);
                              if ( myOptions )
                              {
                                   app.dialog.setSize( myOptions );
                              }
                              // wireup click event for when the user clicks on the greyed out area (outside of the popup)
                              jQuery(".ui-widget-overlay").click(function() {
                                  app.dialog.close();
                             });
                              
                              
                              
                              jQuery(".ui-dialog-titlebar-close").click(function() {
                                  app.dialog.close();
                             });
                              
                              jQuery("body").triggerHandler("dialogOpen");
                              
                              
                         }
                    };
                    app.dialog.customOptions = myOptions;
                    if ( myOptions )
                    {
                         if ( myOptions.type ) {
                              newOptions.type = myOptions.type;
                         }
                         if ( myOptions.data ) {
                              newOptions.data = myOptions.data;
                         }
                    }
                    app.ajax.load( newOptions );
                    //alert("Length: " + jQuery(".ui-widget-overlay").length);
                    
                    
               },
               
               // opens a dialog from existing page content
               hopUp : function(title, dialogClass, myOptions) {
                    // create the dialog container if not present already
                    if(jQuery("#dialogcontainer").length === 0) {
                         jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
                    }

                    // set a default title
                    title = title || "";
                    
                    //set a default class
                    dialogClass = dialogClass || "";

                    // finally load the dialog, set the dialog title
                    app.dialog.checkOpen(myOptions);
                    app.dialog.setTitle(title);
                    app.dialog.setClass(dialogClass);
                    app.dialog.setSize(myOptions);
                    
                    // wireup click event for when the user clicks on the greyed out area (outside of the popup)
                    jQuery(".ui-widget-overlay").click(function() {
                        app.dialog.close();
                   });
               },

               // initializes the dialog with common dialog actions, like closing upon canceling
               // use this function in the dialog rendering template to re-bind common actions
               // upon dialog reload
               init : function() {
                    jQuery(document).ready(function() {
                         // binds the action to all buttons defining an action through the "name" attribute
                         jQuery("#dialogcontainer button").each(function() {
                              jQuery(this).click(function() {
                                   var action = jQuery(this).attr("name");
                                   if(action) {
                                        app.dialog.submit(action);
                                   }
                                   return false;
                              });
                         });

                         // cancel button binding
                         jQuery("#dialogCancelBtn").click(function() {
                              app.dialog.close();
                              return false;
                         });
                         
                    });
               },

               // sets the title of the dialog
               setTitle : function(title) {
                    jQuery("#dialogcontainer").dialog("option", "title", title);
               },
               
               // sets the class of the dialog
               setClass : function(className) {
                    jQuery("#dialogcontainer").addClass(className);
                    jQuery(".ui-dialog-titlebar").addClass(className);
                    jQuery("#dialogcontainer").addClass(className+"-container");
                    jQuery(".ui-dialog-titlebar").addClass(className+"-titlebar");
                    this.dialogClass = className;
               },               
               

               // checks, if the dialog is in the state "open" and sets the state if not presently set
               // this function is implicitly called by app.dialog.open(url, title) in order to initialize
               // the dialog properly; use this function to recover the "open" state of a dialog
               checkOpen : function( myOptions) {
                    // 2011 Temp comment for jQuery UI dialog bug 
                    //if(!jQuery("#dialogcontainer").dialog('isOpen'))
                    //{
                         if ( !myOptions )
                         {
                              myOptions = {};
                         }
                         jQuery("#dialogcontainer").dialog({
                              autoOpen: false,
                              modal: true,
                              overlay: {
                                  opacity: 0.9,
                                   background: "#666666"
                              },
                             height: myOptions.outerHeight ? myOptions.outerHeight : 425,
                             width: myOptions.outerWidth ? myOptions.outerWidth : 460,
                             resizable: false,
                             bgiframe: false,
                             position: myOptions.position ? myOptions.position : "center"
                         });
                         
                         jQuery("#dialogcontainer").dialog("open");
                         if(myOptions.uiDialogClass) {
                              jQuery("#dialogcontainer").parents(".ui-dialog").addClass(myOptions.uiDialogClass);
                         }
                    //}
               },
               
               setSize: function( innerWidth, outerWidth, innerHeight, outerHeight )
               {
                    if (typeof innerWidth === 'object' )
                    {
                         outerHeight = ( innerWidth.hasOwnProperty('outerHeight') ? innerWidth.outerHeight : null );
                         innerHeight = ( innerWidth.hasOwnProperty('innerHeight') ? innerWidth.innerHeight : null );
                         outerWidth  = ( innerWidth.hasOwnProperty('outerWidth')  ? innerWidth.outerWidth  : null );
                         innerWidth  = ( innerWidth.hasOwnProperty('innerWidth' )? innerWidth.innerWidth  : null );
                    }
                    if ( innerWidth !== null )
                    {
                         jQuery( "#dialogcontainer" ).width( innerWidth );
                    }
                    if ( innerHeight )
                    {
                         jQuery( "#dialogcontainer" ).height( innerHeight );
                    }
                    // for the outer it is a little bit more sophisticated.
                    if ( outerWidth !== null )
                    {
                         jQuery( "#dialogcontainer" ).dialog( 'option', 'width', outerWidth );
                    }
                    if ( outerHeight )
                    {
                         jQuery( "#dialogcontainer" ).dialog( 'option', 'height', outerHeight );
                    }
               },

               // closes the dialog and triggers the "close" event for the dialog
               close : function() {
                    // close needs to remove the classes that were added...
                    // need to determine what those classes were.
                    if (this.dialogClass !== "")
                    {
                         jQuery("#dialogcontainer").removeClass(this.dialogClass);
                         jQuery(".ui-dialog-titlebar").removeClass(this.dialogClass);
                         jQuery("#dialogcontainer").removeClass(this.dialogClass+"-container");
                         jQuery(".ui-dialog-titlebar").removeClass(this.dialogClass+"-titlebar");
                         jQuery("#dialogcontainer").parents(".ui-dialog").removeClass(this.dialogClass);
                         this.dialogClass = "";
                    }
                    if(app.dialog.customOptions && app.dialog.customOptions.uiDialogClass) {
                         jQuery("#dialogcontainer").parents(".ui-dialog").removeClass(app.dialog.customOptions.uiDialogClass);
                    }
                    jQuery("#dialogcontainer").dialog("close");
                    jQuery(document.body).trigger("dialogClosed");
               },

               // attaches the given callback function upon dialog "close" event
               onClose : function(callback) {
                    if(typeof(callback) !== 'undefined') {
                         jQuery(document.body).bind("dialogClosed", callback);
                    }
               },

               // triggers the "apply" event for the dialog
               triggerApply : function() {
                    jQuery(document.body).trigger("dialogApplied");
               },

               // attaches the given callback function upon dialog "apply" event
               onApply : function(callback) {
                    if(typeof(callback) !== 'undefined') {
                            jQuery(document.body).bind("dialogApplied", callback);
                    }
               },

               // triggers the "delete" event for the dialog
               triggerDelete : function() {
                    jQuery(document.body).trigger("dialogDeleted");
               },

               // attaches the given callback function upon dialog "delete" event
               onDelete : function(callback) {
                    if(typeof(callback) !== 'undefined') {
                      jQuery(document.body).bind("dialogDeleted", callback);
                    }
               },

               // submits the dialog form with the given action
               submit : function(action) {
                    // set the action
                    jQuery("#dialogcontainer form").append("<input name=\"" + action + "\" type=\"hidden\" />");

                    // serialize the form and get the post url
                    var post = jQuery("#dialogcontainer form").serialize();
                    var url = jQuery("#dialogcontainer form").attr("action");

                    // post the data and replace current content with response content
                      jQuery.ajax({
                       type: "POST",
                       url: url,
                       data: post,
                       dataType: "html",
                       success: function(data){
                                jQuery("#dialogcontainer").empty().html(data);
                       },
                       failure: function(data) {

                            alert("Server connection failed!");
                       }
                    });
               }
          },
          // options has to be passed in
          social : function(options) {
               var loginDialogID = "SocialLoginDialog";
               var instance = this;
               var popupBtnSelector = options.popupBtnSelector ? options.popupBtnSelector : ".loginanchorlink";
               var popupBtnClass = "loginanchorlink";
               var popupBtnDivSelector = ".loginlink";
               var redirectURL = options.redirectURL;
               var resources = options.resources;
               
               var credentials = {
                    loginType      : "",
                    ID               : "",
                    displayName     : ""
               };
               
               var facebookEnabled = options.facebookEnabled ? options.facebookEnabled : false;
               var twitterEnabled = options.twitterEnabled ? options.twitterEnabled : false;
               var burtonEnabled = options.burtonEnabled ? options.burtonEnabled : false;
               var facebookCommentAppID = options.facebookAppIDs ? options.facebookAppIDs.comment : "";
               var twitterCommentAppID = options.twitterAppIDs ? options.twitterAppIDs.comment : "";
               
               var facebookButtonHTML = '<fb:login-button size="large" autologoutlink="true" length="long"></fb:login-button>';
               var twitterButtonHTML = '<div id="twitter-connect-placeholder" class="twitterbutton" style="float:left;padding-right:10px;"></div>';
               var burtonButtonHTML = '<a href="'+options.redirectURL+'">'+resources.burtonLogin+'</a>';
               // setup private properties and methods

               var updateCredentials = function(type,ID,displayName, whenString) {
                    credentials.loginType = type;
                    credentials.ID = ID;
                    credentials.displayName = displayName;
                    // let everyone know
                    var eventData = credentials;
                    eventData.when = whenString;
                    
                    //if(type != "") {
                         jQuery(document).trigger("SocialCredentialsChanged", eventData);
                    //}
               };
               var clearLogin = function() {
                    updateCredentials("", "", "");
                    //jQuery(popupBtnDivSelector).html('<span><a  class="'+popupBtnClass+'" href="" title="' + popupBtnLabel.login + '">' + popupBtnLabel.login + '</a></span>');
                    wireupEvents();
               };
               
               var wireupEvents = function() {
                    //alert(popupBtnSelector);
                    jQuery(popupBtnSelector).bind("openSocialLoginWindow", function() {
                         if(twitterEnabled) {
                              twttr.anywhere(function (T) {
                                   if (T.isConnected()) {
                                        ShowTwitterLoggedInState(T);
                                        jQuery("#twitter-connect-placeholder").html("");
                                        jQuery("#twitter-connect-placeholder").append('<br/><button id="signout" type="button">Sign out of Twitter</button>');
                                        jQuery("#signout").click(function () {
                                             twttr.anywhere.signOut();
                                             clearLogin();
                                             return false;
                                        });
                                   } else {
                                        ShowTwitterLoggedOutState(T); 
                                        jQuery("#twitter-connect-placeholder").html("");
                                        T("#twitter-connect-placeholder").connectButton({ size: "large",
                                             authComplete: function(user) {
                                                  jQuery("#"+loginDialogID).dialog("close");
                                                  ShowTwitterLoggedInState(T);
                                                  jQuery(popupBtnDivSelector).html('<br/><button id="signout" type="button">Sign out of Twitter</button>');
                                                  jQuery("#signout").click(function () {
                                                       twttr.anywhere.signOut();
                                                       clearLogin();
                                                  });
                                                                
                                             }
                                       });
                                   }
                              });
                         }
                         // open the dialog
                         //alert("Don't open it yet");
                         jQuery("#"+loginDialogID).dialog("open");
                         return false;
                    });
               };
               // setup the dialog
               if(jQuery("#"+loginDialogID).length === 0)
               {
                    jQuery("body").append("<div id=\""+loginDialogID+"\" style=\"display:none;\"></div>");
                    if(facebookEnabled) 
                         {jQuery("#"+loginDialogID).append('<div class="fbbutton" style="float:left;padding-right:10px;">'+facebookButtonHTML+'</div>');}
                    if(twitterEnabled)
                         {jQuery("#"+loginDialogID).append(twitterButtonHTML);}
                    if(burtonEnabled)
                         {jQuery("#"+loginDialogID).append(burtonButtonHTML);}
               }
               
               
               jQuery("#"+loginDialogID).dialog({
                    autoOpen: false,
                    modal: true,
                    width: 500,
                    height: 300,
                    overlay: {
                         opacity: 0.9,
                         background: "#666666"
                    },
                    title: "Login"
               }); 
               // init functionality should go here
               //console.log("Setting up facebook " + facebookEnabled);
               if(facebookEnabled) {
                    //<div id="fb-root"></div>
                    // this div has to be somewhere on the page in order to work appropriately
                    if(jQuery("#fb-root").length === 0) {
                         jQuery("body").append('<div id="fb-root"></div>');
                    }
                    FB.init({appId: facebookCommentAppID, status: true, cookie: true,xfbml: true});
                    
                    // this is on page load 
                    FB.api('/me', function(response) {
                         updateCredentials(1, response.id, response.name, "PAGE_LOAD");
                         //jQuery(popupBtnDivSelector).html(facebookButtonHTML);
                         FB.init({appId: facebookCommentAppID, status: true, cookie: true,
                             xfbml: true});
                    });
                    
                    // this is after auth changes
                    FB.Event.subscribe('auth.sessionChange', function(response) {
                         if (response.session) {
                              jQuery("#"+loginDialogID).dialog("close");
                              FB.api('/me', function(response) {
                                   updateCredentials(1, response.id, response.name, "USER_SUBMITTED");
                                   //jQuery(popupBtnDivSelector).html(facebookButtonHTML);
                                   FB.init({appId: facebookCommentAppID, status: true, cookie: true,xfbml: true});
                                });
                         }
                        else 
                        { 
                            // revert back to regular sign in screen
                            clearLogin();
                        } 
                    });
               }
               wireupEvents();
               
               
               
               return {
                    facebookEnabled : facebookEnabled,
                    twitterEnabled      : twitterEnabled,
                    burtonEnabled     : burtonEnabled,
                    facebookAppIDs     : options.facebookAppIDs ? options.facebookAppIDs : {},
                    twitterAppIDs     : options.twitterAppIDs ? options.twitterAppIDs : {},
                    getTwitterWidget : function() {
                         var returnHtml = "";
                         return returnHtml;
                    },
                    getFacebookWidget : function() {
                         var returnHtml = "";
                         return returnHtml;
                    },
                    getCredentials : function() {
                         return credentials;
                    }
               };
          }
     };
}(jQuery));

// application initialization on dom ready
jQuery(document).ready(function(){
     app.init();
     // INIT dealers: this checks to see if there are dealers and setup the json call if it needs to happen
     app.dealer.init();
});

//usage: log('inside coolFunc',this,arguments);
//http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
     log.history = log.history || [];   // store logs to an array for reference
     log.history.push(arguments);
     if(this.console){
          console.log( Array.prototype.slice.call(arguments) );
     }
};
