     /**
    * Core functionality
    *
    * @author Mandarin Drummond
    */
    var RP = Class.create();
    
    /**
    * Base class, loads up the stage, icons, widgets, etc.
    *
    * @author Mandarin Drummond
    */
    
    
    
    /**
    * [BEGIN] Configuration options 
    */
    RP.Config = {};
    //debugging
    RP.Config.DEBUG = false;
    //alias
    $RP$DEBUG = RP.Config.DEBUG;
    
    
    RP.Config.CSS = { SAVED_OFR_CNT_DIV: 'rp_saved_cpn_count',
        DEFAULT_CURTAIN_DIV: 'curtain',
        DEFAULT_CLIP_CHECKBOX_PRINT: 'clip_checkbox_print',
        UI_ERR_DIV: 'row_error'
    };
    
    /**
    * Determines which plum class to use..
    */
    RP.Config.PLUM = { HANDLER: 'Plum' };
    
    /**
    * Used to aggregate selected offers for printing
    */
    RP.Config.PRINT = { NONSECURE: 'offr_checkbox',
      SECURE: 'soffr_checkbox',
      MAXCLIPPED: 21
    };
    
    RP.Config.CACHE = { LIFETIME: 300 }; //default cache time in seconds...
    
    RP.Config.COOKIE = { DELIM: '|', //default cookie delimiter
        LIFETIME: 31536000
    };  //cookie lifetime in seconds. (currently set to about a year) 
    
    /**
    * Normalizes user attribute names in the system..
    */
    RP.Config.USER = {};
    RP.Config.USER.UIDCK = "RPUID";   //name of the user id cookie
    RP.Config.USER.USERCK = "RPUSER";   //name of the user cookie 
    RP.Config.USER.ATTR = { ZIP: 'zipCode', //zip code
        LOC_RAD: 'locRadius', //location radius
        LOC_LAT: 'locLat',
        LOC_LON: 'locLon'
    };
    
    /**
    * Centralizewd message resources. Put all message copy in this collection.
    */
    RP.Config.MSG = { INVALID_EMAIL: "Invalid email address.",
        INVALID_EMAIL_CONF: "Your email confirmation does not match your email address.",
        INVALID_SHARED_EMAIL: "One or more of your friends email addresses is invalid.",
        INVALID_NAME: "Please enter your full name.",
        INVALID_FIRSTNAME: "Please enter your first name.",
        INVALID_LASTNAME: "Please enter your last name or initial.",
        INVALID_ZIPCODE: "Invalid ZIP code.",
        INVALID_GENDER: "Please select a gender.",
        INVALID_PHONE: "Invalid phone number.",
        INVALID_EMAIL: "Invalid email address.",
        INVALID_EMAIL_CONF: "Your email confirmation does not match your email address.",
        INVALID_PASSWORD: "Invalid password.",
        INVALID_PASSWORD_CONF: "Your password confirmation does not match your password.",
        INVALID_SECURITY_ANSWER: "Invalid security answer.",
        INVALID_OPTIN: "Please select an optin option.",
        INVALID_DEPARTURE: "Invalid departure location.",
        INVALID_ARRIVAL: "Invalid arrival location.",
        INVALID_DEPARTURE_DATE: "Invalid departure date.",
        INVALID_ARRIVAL_DATE: "Invalid arrival date.",
        SYSTEM_MESSAGING_TITLE_DEFAULT: "RedPlum System Messaging",
        SYSTEM_MESSAGING_COPY_DEFAULT: "We're sorry, there was a problem in our system. Please try again",
        SHARE_MESSAGE_DEFAULT: "Hey check out this offer I found!",
        DINING_NO_LISTINGS: "There are currently no listings for your area.",
        MOVIES_NO_THEATERS: "There are no theaters in your area.",
        ERROR_LOYALTY_NUMBER: "Sorry. There was an problem verifying your number.",
        INVALID_LOYALTY_NULL: "Please enter your Loyalty Card Number.",
        ERROR_LOYALTY_SAVE: "Sorry. There was a problem saving your offer.",
        ERROR_LOYALTY_ALREADY_SAVED: "This offer has already been saved to your loyalty card."
    }
    
    /**
    * Centralizewd message resources. Put all message copy in this collection.
    */
    RP.Config.IMG = {
        CTC_SAVED: "themes/coupon/images/icons/saved_ctc.png"
    
    }
    
    
    /**
    * Widget type definitions
    *
    */
    
    /**
    * @see RP.EventEffect, RP.Effect in rp.effects.js - 'bubbleZoom', 'hoverZoom', etc.
    */
    
    
    RP.Config.AUTH_CHK_CLASS = { SECURE_BUTTON: 'RP_secure_btn' };
    
    //Used for global variables
    RP.Config.GLOBAL = { NS: 'RP',     //default namespace
        SYSTEM_MESSAGING_CONTAINER: 'container_utility_messaging'
    };  //system messaging utility overlay id
    
    RP.Config.CONTENT_TYPES = { OFFER: 1,
        BANNER: 5
    }
    
    RP.Config.PREMIUM_TYPES = { PLATINUM: 4,
        GOLD: 3,
        SILVER: 2
      };
    
    RP.Config.CLIP_PRINT_COOKIE_NAME = "clipPrint";
    
    /** [BEGIN] DO NOT CHANGE THESE VALUES -MED 12/12/2008**/
    //RP.Config.BASE_URL = 'http://VALWCPWS001VM:21001/';
    //RP.Config.SECURE_URL = 'http://VALWCPWS001VM:21001/';
    RP.Config.BASE_URL = 'https://www.pgesaver.com/';
    RP.Config.SECURE_URL = 'https://www.pgesaver.com/';
    RP.Config.MEDIA_URL = 'http://admin-dev.redplum.com/media/';
    RP.Config.OFFER_BASE_URL = 'https://www.pgesaver.com/offers/';
    /** [END] DO NOT CHANGE THESE VALUES -MED 12/12/2008**/
    /**                      
    RP.Config.BASE_URL              = 'http://www.pgesaver.com/'; 
    RP.Config.SECURE_URL            = 'https://www.pgesaver.com/'; 
    RP.Config.MEDIA_URL             = 'http://admin-dev.redplum.com/media/';
    RP.Config.OFFER_BASE_URL        = 'http://VALWCPWS001VM:21001/offers/';
    RP.Config.TEMPLATE_PAGE_PATH    = 'Pages';
    */
    /**
    * [END] Configuration options 
    */
    
    
    /** 02/19/2008 SN -  begin script proted over from ui.class.js */
    /**
    * The UI class
    *
    * @author Scott Noring
    * @author Mandarin Drummond
    */
    
    var _expdate = new Date();
    _expdate.setTime(_expdate.getTime() + (1000 * 60 * 60 * 24 * 365)); //365 sets cookie to expire in one year. change to 30 for a month
    var _desktopWidth = ""; //set dynamically 
    var _desktopHeight = ""; //set dynamically 
    var _dashWidth = ""; //set dynamically
    var _rateTimer;
    var _rateObj;
    var _rateImagePath = RP.Config.BASE_URL + "themes/coupon/images/misc/stars";
    var _currentPath = "../";
    var $RP$CTX = RP;
    
    if (pageName = "Home") {
        _currentPath = ""
    }
    
    RP.UI = {}
    
    
    RP.UI.controlCurtain = function (state) {
      var element = "curtain";
      if (browser == "Internet Explorer") {
        element = "curtainAlt";
      }
      if ($(element)) {
        $(element).setStyle({ height: _desktopHeight });
        $(element).setStyle({ visibility: state });
      }
    
    }
    
    RP.UI.getDesktopWidth = function() {
    
        if (window.innerWidth) {
            _desktopWidth = window.innerWidth;
        } else {
            _desktopWidth = document.body.clientWidth;
        }
    
        return _desktopWidth;
    }
    
    RP.UI.getDesktopHeight = function () {
      if (window.innerHeight) {
        _desktopHeight = window.innerHeight;
      } else {
        _desktopHeight = document.body.clientHeight;
      }

    
      return _desktopHeight;
    
    }
    
    RP.UI.GetQueryParam = function(arg) {
        params = window.location.search.substring(1);
        param = params.split("&");
        for (i = 0; i < param.length; i++) {
            paramValue = param[i].split("=");
            if (paramValue[0] == arg) {
                return paramValue[1];
            }
        }
    }
    
    
    RP.UI.controlUtility = function(state, title, id, url, hideCloseControl, whichUtility, msg) {
      // this is to reset scroll state after setting it to scroll for privacy
      if ($('frameUtility')) {
        $('frameUtility').setStyle({ 'overflow': 'auto' });
      }
      if (!whichUtility) {
        whichUtility = 'container_utility';
      }
      var utilityObj = $(whichUtility);
      var utilityTitle = $('utility_header_title');
      if (whichUtility == 'container_utility_messaging') {
        utilityTitle = $('utility_messaging_header_title');
      }
      var utilityFrame = window.frames['frameUtility'];
      if (whichUtility == 'container_utility_messaging') {
        utilityFrame = window.frames['frameUtility_messaging'];
      }
      //var utilityIndicatorObj = $('utility_indicator');
      if (state == 'visible') {
    
        //if(hideCloseControl){ $('utility_header_close').setStyle({display : 'none'});}
        //write title to overlay
    
        if (title) utilityTitle.innerHTML = title;
        //load frame with url
    
        if (url) {
          if (whichUtility == 'container_utility_messaging') {
            $('container_utility_messaging_content_frame').setStyle({ 'display': 'block' });
            $('container_utility_messaging_content_noframe').setStyle({ 'display': 'none' });
          }
          utilityFrame.location = url;
        }
    
        if (msg) {
          $('container_utility_messaging_content_frame').setStyle({ 'display': 'none' });
          $('container_utility_messaging_content_noframe').setStyle({ 'display': 'block' });
          $('container_utility_messaging_msg').update(msg);
        }
        //turn overlay on if state, turning on overlay from inner pages onload
    
        RP.UI.positionOverlay(whichUtility);
    
      }
    
      if (state == 'hidden') {
        if (utilityFrame) {
          utilityFrame.location = 'about:blank';
        }
        if ($('container_default_overlay').style.visibility != 'visible') {
          RP.UI.setFlashVisibility('visible');
        }
        // RP.UI.setPlumVisibility('visible');
    
    
        //set focus back to the top of the document
    
    
      } else {
        //If the offer overlay is on then dont turn the flash objects back on
    
        RP.UI.setFlashVisibility('hidden');
    
        //RP.UI.setPlumVisibility('hidden');
      }
    
      if (state) {
        RP.UI.controlCurtain(state);
        // $('curtain').setStyle({visibility : state});
        utilityObj.style.visibility = state;
    
    
        /*2233 - reset the focus to the top of the iframe top */
        if (state == 'hidden') {
          var currentLocation = location.href;
          currentLocation = currentLocation.replace('#top', '');
          document.location.href = currentLocation + '#top';
        }
      }
    }
    
    
    RP.UI.positionOverlay = function(id, topPos, botPos) {
      var overlayObj = $(id);
      if (overlayObj) {
        var overlayObjWidth = overlayObj.offsetWidth / 2;
        var overlayPosLeft = RP.UI.getDesktopWidth() / 2 - overlayObjWidth;
        var overlayPosTop = RP.UI.scrollY() + 40;
    
        if (overlayObjWidth == 0) {
          overlayPosLeft = 400;
        }
        
        /* SN 5115 - fix for cut off right edge in ie8 */
        if (browser == 'Internet Explorer' & version >= '8') {
          overlayPosLeft = overlayPosLeft - 20;
        }
    
        //set left position
        overlayObj.setStyle({ left: "270px" });
        //set top position
        overlayObj.setStyle({ top: overlayPosTop + "px" });
        //alert(overlayPosTop);
    
        //if(topPos) overlayObj.setStyle({top : topPos + "px"});
        //if(botPos) overlayObj.setStyle({bottom : botPos + "px"});
      }
    }
    
    RP.UI.scrollY = function() {
        // A shortcut, in case we’re using Internet Explorer 6 in Strict Mode
        var de = document.documentElement;
    
        // If the pageYOffset of the browser is available, use that
        return self.pageYOffset ||
    
        // Otherwise, try to get the scroll top off of the root node
            (de && de.scrollTop) ||
    
        // Finally, try to get the scroll top off of the body element
            document.body.scrollTop;
    }
    
    RP.UI.resizeUtilityFrame = function(adjustmentVal) {
        var utilityFrameObj = parent.$('frameUtility');
        if (browser == "Internet Explorer") {
            adjustmentVal = adjustmentVal * 2;
        }
    
        if ($('contentHeight')) {
    
            var contentHeight = $('contentHeight').getHeight() + adjustmentVal;
            utilityFrameObj.setStyle({ height: contentHeight + "px" });
    
        }
    
        parent.RP.UI.globalInit();
    }
    
    
    RP.UI.setFlashVisibility = function(state) {
        var flashObj = document.getElementsByClassName("flash_container");
        if ($('home_frame_plum_picks')) {
            $('home_frame_plum_picks').setStyle({ visibility: state });
        }
    
        if (flashObj) {
            for (i = 0; i < flashObj.length; i++) {
                flashObj[i].setStyle({ visibility: state });
            }
        }
    }
    
    
    RP.UI.doLogout = function() {
        var successCallBackFunc = function() {
    
            /**
            * Using the preferred show()/hide() prototype methods
            *
            */
    
            //parent.$('header_subnav_2').setStyle({'visibility' : 'visible'});
            //parent.$('header_subnav_3').setStyle({'visibility' : 'hidden'});
            if ($('header_subnav_2')) {
                $('header_subnav_2').show();
                $('header_subnav_3').hide();
            }else if ($('header_subnav_2_iframe')) {
                $('header_subnav_2_iframe').show();
                $('header_subnav_3_iframe').hide();
            } 
    
            window.location = RP.Config.BASE_URL;
            
            /**
            * MD, 10192007, commented out because it is causing an error
            */
            //window.top.reload();
        }
        var failureCallBackFunc = function() {
            //parent.$('header_subnav_2').setStyle({'visibility' : 'hidden'});
            //parent.$('header_subnav_3').setStyle({'visibility' : 'visible'});
            if ($('header_subnav_2')) {
                $('header_subnav_2').hide();
                $('header_subnav_3').show();
            
            }else if ($('header_subnav_2_iframe')) {
                $('header_subnav_2_iframe').hide();
                $('header_subnav_3').show();
            } 
        }
        RP.User.logout(successCallBackFunc, failureCallBackFunc);
    }
    
    /** Methods to Build Common Buttons
    *
    * @author Scott Noring
    * may end up putting this into one method and pass action
    */
    
    RP.UI.buildShareButton = function(btnClass, btnSecureClass, btnStyle, btnTxt, offerId, pageInfoCategory, OfferVendorId, OfferVendorName, IsSecure) {
        var btnObj = "<a href=\"javascript:void(0)\" class=\"" + btnSecureClass + " " + btnClass + "\" style=\"" + btnStyle + "\" onclick=\"javascript:if(this.className== '" + btnSecureClass + " " + btnClass + "');$RP$CTX.UI.controlUtility('visible','Send this offer to friends','','" + RP.Config.BASE_URL + "utility/Share.aspx?offer=" + offerId + "','');$RP$CTX.Tracking.setInteraction(this,'" + offerId + "','Send','" + pageInfoCategory + "','" + OfferVendorId + "','" + OfferVendorName + "','" + IsSecure + "')\" title=\"Send to Friend\" >";
        btnObj += btnTxt;
        btnObj += "</a>";
        return btnObj;
    }
    
    RP.UI.buildSaveButton = function(btnClass, btnSecureClass, btnStyle, btnTxt, offerId, isWithinSaved, srcDiv, pageInfoCategory, OfferVendorId, OfferVendorName, IsSecure) {
        var btnId = srcDiv + "_" + offerId;
        var btnObj = "<a href=\"javascript: void(0);\" id=\"" + btnId + "\" class=\"" + btnSecureClass + " " + btnClass + "\" style=\"" + btnStyle + "\" onclick=\"javascript:$RP$CTX.UI.saveOfferWithAnimation('" + offerId + "','" + isWithinSaved + "', '" + srcDiv + "'); $('" + btnId + "').addClassName('button_list_offer_disabled');$RP$CTX.Tracking.setInteraction(this,'" + offerId + "','Save','" + pageInfoCategory + "','" + OfferVendorId + "','" + OfferVendorName + "','" + IsSecure + "');return false;\" title=\"Save to my saved coupons\">";
        btnObj += btnTxt;
        btnObj += "</a>";
        return btnObj;
    }
    
    RP.UI.buildPrintButton = function(btnClass, btnSecureClass, btnStyle, btnTxt, offerId, isSecure, pageInfoCategory, OfferVendorId, OfferVendorName, IsSecure) {
    
        var btnObj = "<a href=\"javascript:void(0)\" class=\"" + btnSecureClass + " " + btnClass + "\" style=\"" + btnStyle + "\" title=\"Print offer\" onclick=\"javascript: $RP$CTX.UI.controlUtility('visible','Printing Offers','',$RP$CTX.UI.buildPrintUrl('" + offerId + "', " + isSecure + "));$RP$CTX.Tracking.setInteraction(this,'" + offerId + "','Print','" + pageInfoCategory + "','" + OfferVendorId + "','" + OfferVendorName + "','" + IsSecure + "');\">";
        btnObj += btnTxt;
        btnObj += "</a>";
        return btnObj;
    }
    
    
    RP.UI.buildPrintUrl = function(offerId, isSecure) {
    
        if (isSecure) {
            var url =  RP.Config.BASE_URL + "Print.aspx?pd=" + $RP$CTX.Printer.getDeviceId() + "&soffers=" + offerId;
        } else {
            var url = RP.Config.BASE_URL + "Print.aspx?pd=1&offers=" + offerId;
        }
        return url;
    }
    
    RP.UI.setPrintCallback = function(offerId, offerIsSecure) {
        var func = function() {
            var handle = $RP$CTX;
            var url = $RP$CTX.UI.buildPrintUrl(offerId, offerIsSecure);
            handle.UI.controlCurtain('none');
            handle.UI.controlUtility('visible', 'Printing Offers', '', url);
        }
        RP.Util.setGlobal('callBack', func, 'Print');
    }
    
    
    RP.UI.saveOfferWithAnimation = function(OfferId, isWithinSaved) {
        //show loader?
    
        function succCallBack(resp) {
    
            if (resp.Status == "Success") {
                //position indicator
                var objPosLeft = Position.cumulativeOffset($('header_saved_coupons'))
                objPosLeft = objPosLeft[0];
                $('container_saved_indicator_wrapper').setStyle({ left: objPosLeft + "px" })
                //turn on indicator
                $('container_saved_indicator_wrapper').show();
                $('container_saved_indicator_wrapper').setStyle({ 'visibility': 'visible' });
                //turn off indicator after 4 sec
                window.setTimeout('Effect.Fade(\'container_saved_indicator_wrapper\');', 4000);
                //window.setTimeout('$(\'container_saved_indicator_wrapper\').setStyle({\'visibility\' : \'hidden\'})',4000);
                $('saved_indicator_num_saved').update(RP.User.Content.GetSavedOfferCount());
                $('rp_saved_cpn_count').update(RP.User.Content.GetSavedOfferCount());
    
                /** If the offer (premium) is saved from with 'My saved coupons' then reload widget' */
                if (isWithinSaved &&
                   isWithinSaved != 'false' &&
                   isWithinSaved != 'undefined') {
    
                    window.top.refresh();
                }
    
            } else {
                var err = $RP$ERR;
                err.addMessage(resp.Message);
                //alert(resp.Message);
            }
    
            //hide loader?
        }
        //alert(OfferId);
        var arr = new Array();
        arr.push(OfferId);
    
        RP.User.Content.AddSavedOffers(arr, succCallBack);
    
    }
    
    //used on new Grocery Match page
    RP.UI.saveOfferWithAnimation2 = function(OfferId, isWithinSaved, confId, confLoadingId,saveBtnId) {
    
    
        function succCallBack(resp) {
                var confObj = $(confId);
                var loadingObj = $(confLoadingId)
            if (resp.Status == "Success") {
                $('saved_indicator_num_saved').update(RP.User.Content.GetSavedOfferCount());
                $('rp_saved_cpn_count').update(RP.User.Content.GetSavedOfferCount());
                
    
              
                //turn on confirmation
                confObj.setStyle({ display: 'block' });
                $(saveBtnId).addClassName('button_list_offer2_disabled');
            } else {
                var err = $RP$ERR;
                err.addMessage(resp.Message);
                alert(resp.Message);
            }
                //reset loading icon to off
                loadingObj.down().src = "";
                loadingObj.setStyle({ display: 'none' });
           
        }
    
        var arr = new Array();
        arr.push(OfferId);
        //set src of loading icon so animition starts at beginning
        $(confLoadingId).down().src = RP.Config.BASE_URL + "themes/coupon/images/icons/bar_large2.gif";
        //turn on loading icon
        $(confLoadingId).setStyle({ display: 'block' });
        RP.User.Content.AddSavedOffers(arr, succCallBack);
    
    }
    
    RP.UI.saveCouponDisabled = function(id) {
      $(id).setStyle({ display: 'block' });
    }
    
    RP.UI.setCurtainDimensions = function() {
      var curtainObj = $('curtain');
      //used for IE since it does not support PNG alpha
      var curtainAltobj = $('curtainAlt');
      if (curtainObj) {
        curtainObj.setStyle({ height: $('body').getHeight() + "px" });
        curtainAltobj.setStyle({ height: $('body').getHeight() + "px" });
    
       curtainObj.setStyle({ width: $('body').getWidth() + "px" });
       curtainAltobj.setStyle({ width: $('body').getWidth() + "px" });
      }
    
    }
    
    
    RP.UI.captureDocumentAttributes = function() {
    
        //_desktopHeight = $('contentHeight').getHeight();
      //  _desktopWidth = $('contentHeight').getWidth()
    }
    
    RP.UI.globalInit = function() {
        //set Global document
        RP.UI.captureDocumentAttributes();
        RP.UI.setCurtainDimensions();
    
        /*NOTE:if we need to scale back anything for performance, this can go
        
        * makes both columns have equal height 
        */
        //$RP$CTX.UI.setPageColumnHeights();
    
    
    
    }
    
    RP.UI.getFlashMovieObject = function(movieName) {
        if (window.document[movieName]) {
            return window.document[movieName];
        }
        if (browser != "Internet Explorer") {
            if (document.embeds && document.embeds[movieName])
                return document.embeds[movieName];
        }
        else {
            return document.getElementById(movieName);
        }
    }
    
    RP.UI.StopFlashMovie = function(movieName) {
        var flashMovie = RP.UI.getFlashMovieObject(movieName);
        flashMovie.StopPlay();
    }
    
    RP.UI.PlayFlashMovie = function(flashMovie) {
        var flashMovie = RP.UI.getFlashMovieObject(movieName);
        flashMovie.Play();
    
    }
    
    
    RP.UI.setLeftNavState = function() {
        var tabContainer = $('left_nav_primary');
        if (tabContainer) {
            leftNavObj = tabContainer.getElementsBySelector('li');
    
            for (i = 0; i < leftNavObj.length; i++) {
                leftNavObj[i].down(0).removeClassName('selected');
            }
            //if a pageName var exists on the page highlight left nav item.
            //if a page needs a highlighted left nev then it needs a pageName
            if ($('left_nav_tab_' + pageName)) $('left_nav_tab_' + pageName).addClassName('selected');
        }
    }
    
    
    
    /** display loading animation while page loads
    * @ author Scott Noring
    */
    
    
    RP.UI.resize = function(id, height, width) {
        $(id).setStyle({ width: height + 'px' });
        $(id).setStyle({ height: width + 'px' });
    }
    
    RP.UI.checkCookiesAcceptance = function() {
        document.cookie = "testCookie=true";
        var nameEQ = "testCookie=";
        var checkResult = false;
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) {
                checkResult = true;
                return checkResult;
            }
        }
        return checkResult;
    }
    
    RP.UI.goToSearch = function(obj) {
        var searchInputObj = $(obj).up(1);
        searchInputObj = $(searchInputObj.id).getElementsBySelector('input');
        //go to search page with search val appended
        RP.UI.goTo('Search.aspx?sv=' + $(searchInputObj[0].id).value);
    }
    
    /** Primary tabs control state */
    RP.UI.setContentState = function(indx, containerCssClass) {
        var tabsObjCollection = $('tabs_primary');
        var containerObjCollection = document.getElementsByClassName(containerCssClass);
        tabsObjCollection = tabsObjCollection.getElementsBySelector("li");
    
        for (i = 0; i < tabsObjCollection.length; i++) {
            tabsObjCollection[i].removeClassName('selected');
        }
        //turn active tab on
        tabsObjCollection[indx].addClassName('selected')
    
        //turn content off
        for (j = 0; j < containerObjCollection.length; j++) {
            var contentCol = containerObjCollection[j];
            $(contentCol.id).setStyle({ display: 'none' });
        }
        //turn active content on
        var activeContent = containerObjCollection[indx];
        $(activeContent.id).setStyle({ display: 'block' });
    }
    
    /** Sub tabs control state - used in offer and article lists*/
    RP.UI.setSubTabState = function(layoutType, subTabId, indx, containerCssClass) {
        var containerObjCollection = $('content_container_' + layoutType);
        var tabsObjCollection = $(subTabId);
        tabsObjCollection = tabsObjCollection.getElementsBySelector("a");
        listObjCollection = containerObjCollection.getElementsByClassName(containerCssClass);
        //turn tabs off
        for (i = 0; i < tabsObjCollection.length; i++) {
            tabsObjCollection[i].removeClassName('selected');
        }
        //turn active tab on
        tabsObjCollection[indx].addClassName('selected')
    
        //turn list off
        for (j = 0; j < listObjCollection.length; j++) {
            var listCol = listObjCollection[j];
            $(listCol.id).setStyle({ display: 'none' });
        }
        //turn active list on
        var activeList = listObjCollection[indx];
        $(activeList.id).setStyle({ display: 'block' });
    }
    
    
    RP.UI.showChangeLocation = function(locationRevealObj, locationSwitcherObj) {
        $(locationRevealObj).hide();
        $(locationSwitcherObj).show();
    }
    //Currently just used for returning buttons to default state 
    RP.UI.setOfferButtonState = function(id, state) {
        var btnCollection = $('ListOfferTabs_' + id).getElementsBySelector('a');
        for (i = 0; i < btnCollection.length; i++) {
            btnCollection[i].removeClassName('selected');
        }
        RP.UI.globalInit();
    }
    
    RP.UI.setOfferSubContainerState = function(id, state) {
        var moreInfoContainer = $('OfferMoreInfoContainer_' + id);
        var moreOffersContainer = $('OfferMoreOffersContainer_' + id);
        var moreLocationsContainer = $('OfferLocationsContainer_' + id);
    
        if (moreInfoContainer) moreInfoContainer.setStyle({ display: 'none' });
        if (moreOffersContainer) moreOffersContainer.setStyle({ display: 'none' });
        if (moreLocationsContainer) moreLocationsContainer.setStyle({ display: 'none' });
    }
    
    
    
    RP.UI.setPageColumnHeights = function() {
        /** author: Scott Noring
        * Used across all two column pages to make the column lengths equal
        */
        var col1Obj = $('column1');
        var col2Obj = $('column2');
        var col3Obj = $('column3');
        var col4Obj = $('column4');
    
        if (col1Obj && col2Obj) {
            var col1Height = col1Obj.getHeight();
            var col2Height = col2Obj.getHeight();
    
            if (col1Height < col2Height) {
                col1Height = col2Height;
            } else {
                col2Height = col1Height;
            }
    
            col1Obj.setStyle({ height: col1Height + "px" });
            col2Obj.setStyle({ height: col2Height + "px" });
        }
        //if page is two tabbed
        if (col3Obj && col4Obj) {
            var col3Height = col3Obj.getHeight();
            var col4Height = col4Obj.getHeight();
    
            if (col3Height < col4Height) {
                col3Height = col4Height;
            } else {
                col4Height = col3Height;
            }
    
            col3Obj.setStyle({ height: col3Height + "px" });
            col4Obj.setStyle({ height: col4Height + "px" });
        }
    
    }
    
    RP.UI.preloadImages = function() {
        var args = RP.UI.preloadImages.arguments;
        var preloadedImage = "";
        var pathRoot = RP.Config.BASE_URL + "themes/coupon/images/";
    
        if (pageName == "Home") {
            pathRoot = "themes/coupon/images/";
        }
    
        [args].each(function(args, index) {
            preloadedImage = new Image();
            preloadedImage.src = pathRoot + args[index];
        });
    }
    
    
    var _currentVendorId = ""
    
    RP.UI.controlBubbleOverlay = function(anchor, state, leftOffsetAdj, topOffsetAdj, indicatorPosition, contentWidth, contentHeight, widthAdj, heightAdj) {
        var obj = $('container_bubble_primary');
        var bubbleContentObj = $('container_bubble_inner_content');
        // RP.UI.BubbleLoadStart();
    
        if (state == 'show') {
            var coord = Position.cumulativeOffset($(anchor));
            //var coordLeft = coord[0];
            if (contentWidth) {
                bubbleContentObj.setStyle({ width: contentWidth + "px" });
            } else {
                //not sure yet
            }
            var coordTop = coord[1];
            var overlayObjWidth = obj.offsetWidth / 2;
            var overlayObjHeight = obj.offsetHeight / 2;
            var coordLeft = RP.UI.getDesktopWidth() / 2 - overlayObjWidth;
            //var coordTop = RP.UI.scrollY() + 119;
            coordTop = coordTop  - 100;
    
            if (browser == "Internet Explorer") {
                leftOffsetAdj = parseInt(leftOffsetAdj) - 40;
                topOffsetAdj = parseInt(topOffsetAdj) + 10;
            }
    
            //if (leftOffsetAdj) coordLeft = coordLeft + parseInt(leftOffsetAdj);
            //if (topOffsetAdj) coordTop = coordTop + parseInt(topOffsetAdj);
    
    
    
            obj.setStyle({ left: coordLeft + "px", top: coordTop + "px" });
            obj.style.visibility = "visible";
            RP.UI.controlCurtain('visible');
            //_currentBubbleOffsetTop = coordTop;
    
        } else {
            obj.style.visibility = "hidden";
            RP.UI.controlCurtain('hidden');
        }
    }
    
    //Offer list concentric update progress style
    RP.UI.setLoyaltyProgressLoaderStyle = function(hght) {
        var parentContainerObj = $('container_bubble_content');
        var progressObj = $('bubble_loader');
        //set width and height
    
        var objHeight = $(parentContainerObj).getHeight();
        if (hght) objHeight = hght;
        var widthAdj = 0;
        var heightAdj = 0;
    
        if (browser == "Internet Explorer") {
            widthAdj = 20;
            heightAdj = 10;
        }
        progressObj.setStyle({ width: $(parentContainerObj).getWidth() + widthAdj + "px" });
        progressObj.setStyle({ height: objHeight + heightAdj + "px" });
    
    
        //set opacity of curtain
        new Effect.Opacity(progressObj, { duration: 0.1, from: 0.0, to: 0.8 });
        //progressObj.setStyle({display : "block"});
        //return true
    }
    
    RP.UI.BubbleLoadStart = function() {
        $('bubble_loader').show();
    }
    
    RP.UI.BubbleLoadComplete = function() {
        RP.UI.setLoyaltyProgressLoaderStyle();
        $('bubble_loader').hide();
    }
    
    /* BEGIN new Loyalty functions */
    
    _currentObj = "";
    _currentSavedObj = "";
    _currentLoyaltyProgramId = "";
    _currentLoyaltyOfferId = "";
    _currentLoyaltyIndx = "";
    _currentBubbleOffsetTop = 0;
    _loyaltyCardImageFront = new Array();
    _loyaltyCardImageFront[0] = '';
    
    _loyaltyCardImageBack = new Array();
    _loyaltyCardImageBack[0] = '';
    _loyaltyDoVerify = false;
    
    RP.UI.PrepareSaveCTC = function(id, offerId, offerTitle, offerSummary, currentObj, currentSavedObj) {
        var obj = $('container_bubble_primary');
    
        var bubbleContainerObj = $('container_bubble_inner_content');
        var htm = "";
    
    
        if (RP.User.isAuthenticated()) {
            RP.UI.controlBubbleOverlay(id, 'show', '100', '-71', '', '340', '');
            RP.UI.setLoyaltyProgressLoaderStyle(180);
            RP.UI.BubbleLoadStart();
            //clear programID from memory
            RP.UI.LoyaltyManageProgramId();
            RP.UI.LoyaltyManageCurrentObj(currentObj, currentSavedObj);
            htm = '<div style="font-weight:bold">' + offerTitle + ' - ' + offerSummary + '</div>';
            htm += '<br class="clear"/>';
            htm += '<div class="loyalty_num_container">';
            htm += '<div class="loyalty_label">Loyalty Card:</div>';
            htm += '<div id="LoyaltyCard">';
            htm += '<select id="DdlLoyaltyCards" name="DdlLoyaltyCards" style="width:180px" onChange="$RP$CTX.UI.SetLoyaltyProgram(this.selectedIndex, this.options[this.selectedIndex].value)">';
            htm += '<option>choose one...</option>';
            htm += '</select>';
            htm += '</div>';
            //htm += '<input type="checkbox" id="ChkLoyalty" style="margin-right:4px"/><div style="margin-top:4px;font-size:10px;">save as default</div>';
            htm += '</div>';
            htm += '<br class="clear"/>';
            htm += '<div id="TxtLoyaltyContainer" class="loyalty_num_container" style="display:none">';
            htm += '<div class="loyalty_label">Loyalty Card #:</div>';
            htm += '<div><input type="text" id="TxtLoyaltyInfo" style="width:100px"/></div>';
            //htm += '<div><a href="javascript:void(0)" id="BtnLoyaltySave" onclick="$RP$CTX.UI.LoyaltyDoSave()" class="button_list_offer2" style="display:block">save to card</a></div>';
            htm += '<br class="clear"/>';
            htm += '<div style="margin:0px 0px 0px 100px"><a href="javascript:RP.UI.ShowCardBack()" style="font-size:10px;">where is my number?</a></div>';
            htm += '<br class="clear"/>';
            htm += '<div class="loyalty_label" style="margin-top:4px">Alternate ID:</div>';
            htm += '<div style="margin-top:4px"><input type="text" id="TxtLoyaltyAltId" style="width:100px"/></div>';
            htm += '<div style="margin-top:4px"><a href="javascript:void(0)" id="BtnLoyaltySave" onclick="$RP$CTX.UI.LoyaltyDoSave()" class="button_list_offer2" style="display:block">save to card</a></div>';
            htm += '<br class="clear"/>';
            htm += '<div id="loyalty_error" style="display:none;width:240px;margin:6px 0px 0px 16px" class="utility_text_error"></div>';
            htm += '<div id="loyalty_verify" style="display:none;margin:10px 0px 0px 16px" >';
            htm += '<div>This card is registered to <span id="loyalty_name" style="font-weight:bold"></span>.</div>';
            htm += '<br class="clear"/>';
            htm += '<div style="margin-top:4px"><div>Is this you?</div><div style="margin-left:4px"><a href="javascript:void(0)" id="BtnLoyaltyVerifyYes" onclick="$RP$CTX.UI.LoyaltyDoSave()" class="button_list_offer2">yes</a><a href="javascript:void(0)" id="BtnLoyaltyVerifyNo" onclick="$RP$CTX.UI.LoyaltyControlVerifyCancel(\'show\')" class="button_list_offer2" style="margin-left:6px">no</a></div></div>';
            htm += '</div>';
            htm += '<div id="loyalty_verify_cancel" style="display:none;width:300px;margin:6px 0px 0px 0px" >';
            htm += 'Please enter a new loyalty card number or select a new card';
            htm += '</div>';
            htm += '<div id="loyalty_confirmation" style="display:none;width:300px;margin:10px 0px 0px 0px" >';
            htm += 'Thank you. Your offer has been saved to your card. You can view your saved offers at <a href="' + RP.Config.BASE_URL + 'pages/Saved-Coupons.aspx">My Saved Offers</a>';
            htm += '</div>';
            htm += '<br class="clear"/>'
    
            htm += '</div>';
            htm += '<div class="loyalty_card_container" id="LoyaltyCardContainer">';
            htm += '<img id="ImgLoyaltyCard" src="" />';
            htm += '</div>';
    
            bubbleContainerObj.update(htm);
            RP.UI.GetLoyaltyPrograms(offerId);
            RP.UI.LoyaltyControlImage('', 'hide');
    
        } else {
    
            htm = '<div style="padding:10px 6px 30px 6px;font-size:16px;font-weight:strong;text-align:center;line-height:22px">';
            htm += 'Please <a href= "' + RP.Config.SECURE_URL + 'secure/Login.aspx" style="font-size:16px">login</a> or<br/>';
            htm += '<a href= "' + RP.Config.SECURE_URL + 'secure/Join.aspx" style="font-size:16px">create a new account</a> to save<br/>offers to your Loyalty Card.';
            htm += '<div>';
    
            RP.UI.BubbleLoadComplete();
            RP.UI.controlBubbleOverlay(id, 'show', '100', '-71', '', '230', '');
            bubbleContainerObj.update(htm);
            RP.UI.setLoyaltyProgressLoaderStyle();
        }
        //RP.UI.BubbleLoadComplete();
    }
    
    RP.UI.PositionBubble = function(obj, topOffsetAdj) {
        var objTopPos = Position.cumulativeOffset(obj);
        var scrollArr = RP.UI.getScrollXY();
        var objWidth = obj.getWidth();
        var objHeight = obj.getHeight();
        var objBottom = parseInt(objTopPos) + parseInt(objHeight);
        //var newObjTopPos = parseInt(objHeight);
        //newObjTopPos = newObjTopPos[1];
        if (objBottom > scrollArr[1]) {
            obj.setStyle({ top: _currentBubbleOffsetTop - 100 + "px" });
        }
    
    }
    
    RP.UI.getScrollXY = function() {
        var scrOfX = 0;
        var scrOfY = 0;
        if (typeof (window.pageYOffset) == 'number') {
            //Netscape compliant
            scrOfY = window.pageYOffset;
            scrOfX = window.pageXOffset;
        } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
            //DOM compliant
            scrOfY = document.body.scrollTop;
            scrOfX = document.body.scrollLeft;
        } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
            //IE6 standards compliant mode
            scrOfY = document.documentElement.scrollTop;
            scrOfX = document.documentElement.scrollLeft;
        }
        return [scrOfX, scrOfY];
    }
    
    RP.UI.LoyaltySetImageSrc = function(indx, programId, state) {
        _currentLoyaltyIndx = "";
        var imageUrl = '';
        if (indx) var imageUrl = _loyaltyCardImageFront[0];
    
        if (indx != '' & state == 'show') {
            imageUrl = _loyaltyCardImageFront[indx];
        }
        _currentLoyaltyIndx = indx;
        return imageUrl;
    }
    
    RP.UI.LoyaltySetImageBackSrc = function() {
    
        var imageUrl = '';
        if (_currentLoyaltyIndx) {
            imageUrl = _loyaltyCardImageBack[_currentLoyaltyIndx];
        }
    
        return imageUrl;
    }
    
    RP.UI.ShowCardBack = function() {
        var imageObj = $('ImgLoyaltyCard');
        imageObj.src = RP.UI.LoyaltySetImageBackSrc();
    }
    
    
    RP.UI.GetLoyaltyPrograms = function(offerId) {
    
        var prox = RP.Util.WebService.Factory("LoyaltyService");
    
        RP.UI.BubbleLoadStart();
    
        if (offerId) {
    
            var ctxObj = { 'OfferId': offerId };
    
            prox.GetLoyaltyProgramsByOfferId(offerId, RP.UI.HandleGetLoyaltyProgramResponse, null, ctxObj);
        }
    }
    
    RP.UI.HandleGetLoyaltyProgramResponse = function(Response, Context) {
    
        var err = new RP.UI.DisplayError('', 'loyalty_error');
    
    
        //turn off error row and message
        err.clear();
        err.display(false);
    
        if (Response.Status == "Success") {
    
            _currentLoyaltyOfferId = Context.OfferId;
            RP.UI.BuildImageArray(Response);
    
            RP.UI.DisplayLoyaltyPrograms(Response, Context.OfferId);
    
    
        } else {
    
            err.addMessage('Sorry, there wa a problem retrieving loyalty cards.');
            //turn on error
            err.display();
    
        }
    
        RP.UI.BubbleLoadComplete();
    
    }
    
    
    RP.UI.BuildImageArray = function(Response) {
        // reset array
        _loyaltyCardImageFront = [];
        _loyaltyCardImageFront[0] = '';
        _loyaltyCardImageBack = [];
        _loyaltyCardImageBack[0] = '';
        var LoyaltyPrograms = $A(Response.LoyaltyPrograms);
        //[BEGIN] loop
    
        LoyaltyPrograms.each(function(LoyaltyProgramItem, indx) {
            _loyaltyCardImageFront.push(LoyaltyProgramItem.CardFrontImageUrl);
            _loyaltyCardImageBack.push(LoyaltyProgramItem.CardBackImageUrl);
    
        });
    
        //[END] loop 
    }
    
    RP.UI.DisplayLoyaltyPrograms = function(Response, OfferId) {
    
        var LoyaltyPrograms = $A(Response.LoyaltyPrograms);
        var programDdlObj = $('DdlLoyaltyCards');
        var nameObj = $('LoyaltyCard');
        //[BEGIN] loop       
        LoyaltyPrograms.each(function(LoyaltyProgramItem, indx) {
            if (LoyaltyPrograms.length < 2) {
                nameObj.update(LoyaltyProgramItem.Name);
                RP.UI.SetLoyaltyProgram(1, LoyaltyProgramItem.LoyaltyProgramId);
            } else {
                try {
                    programDdlObj.add(new Option(LoyaltyProgramItem.Name, LoyaltyProgramItem.LoyaltyProgramId), null);
                }
                catch (e) { //in IE, try the below version instead of add()
                    programDdlObj.add(new Option(LoyaltyProgramItem.Name, LoyaltyProgramItem.LoyaltyProgramId));
                }
            }
        });
        //[END] loop 
    
        //hide confirmation if already open
        RP.UI.LoyaltyControlConfirmation('hide');
        //hide verify if already open
        RP.UI.LoyaltyControlVerify('hide');
        //hide verify cancel if already open
        RP.UI.LoyaltyControlVerifyCancel('hide');
        //turn off loader
        RP.UI.BubbleLoadComplete();
    }
    
    
    RP.UI.LoyaltyManageProgramId = function(programId) {
    
        if (programId) {
            _currentLoyaltyProgramId = programId;
        } else {
            _currentLoyaltyProgramId = "";
        }
    }
    
    RP.UI.SetLoyaltyProgram = function(indx, programId) {
    
        if (programId) {
            //set programId into Global var
            RP.UI.LoyaltyManageProgramId(programId);
            RP.UI.LoyaltyControlNumberContainer(programId, 'show');
            RP.UI.LoyaltyControlImage(indx, programId, 'show');
    
            RP.UI.LoyaltyControlConfirmation('hide');
            //hide verify if already open
            RP.UI.LoyaltyControlVerify('hide');
            //hide verify cancel if already open
            RP.UI.LoyaltyControlVerifyCancel('hide');
    
        }
    }
    
    RP.UI.LoyaltyControlNumberContainer = function(programId, state) {
    
        var textContainerObj = $('TxtLoyaltyContainer');
        var textObj = $('TxtLoyaltyInfo');
    
        var prox = RP.Util.WebService.Factory("LoyaltyService");
        var ctxObj = {};
        //reset the value to null;
        textObj.value = '';
    
        if (state == 'show') {
            RP.UI.BubbleLoadStart();
            prox.GetCardNumberByLoyaltyProgramId(parseInt(_currentLoyaltyProgramId), RP.UI.HandleGetLoyaltyNumResponse, null, ctxObj);
            textContainerObj.show();
            textObj.focus();
    
    
        } else {
            textContainerObj.hide();
        }
    
        RP.UI.BubbleLoadComplete();
    
    }
    
    RP.UI.HandleGetLoyaltyNumResponse = function(Response) {
        var textContainerObj = $('TxtLoyaltyContainer');
        var textObj = $('TxtLoyaltyInfo');
        var val = Response.Value;
        if (Response.Status == "Success") {
    
            if (val) textObj.value = val;
    
        } else {
            //textObj.value = '';
            _loyaltyDoVerify = true;
    
        }
    
        //RP.UI.BubbleLoadComplete();
    }
    
    RP.UI.LoyaltyManageCurrentObj = function(currentObj, currentSavedObj) {
    
        if (currentObj) {
            _currentObj = currentObj;
            _currentSavedObj = currentSavedObj;
        } else {
            _currentObj = "";
            _currentSavedObj = "";
        }
    
    }
    
    /* Author Scott Noring 
    *  once offer is saved to card set state of icon to already saved
    */
    RP.UI.setAlreadySavedState = function(doSet) {
    
        var saveObj = $(_currentObj);
        var savedObj = $(_currentSavedObj);
    
        if (doSet) {
            saveObj.setStyle({ display: 'none' });
            savedObj.setStyle({ display: 'block' });
        } else {
            saveObj.setStyle({ display: 'block' });
            savedObj.setStyle({ display: 'none' });
            RP.UI.LoyaltyManageCurrentObj();
        }
    
    }
    
    RP.UI.LoyaltyControlVerify = function(state, name) {
        var obj = $('loyalty_verify');
        var nameObj = $('loyalty_name');
        var btnObj = $('BtnLoyaltySave');
        //alert(name);
        //reset this var back to false to allow user to proceed with saving
        _loyaltyDoVerify = false;
    
        if (state == "show") {
            nameObj.update(name);
            btnObj.hide();
            obj.show();
        } else {
            nameObj.update('');
            btnObj.show();
            obj.hide();
        }
    
        RP.UI.BubbleLoadComplete();
    }
    
    RP.UI.LoyaltyControlVerifyCancel = function(state) {
    
        var obj = $('loyalty_verify_cancel');
    
        RP.UI.LoyaltyControlVerify('hide');
    
        if (state == "show") {
            obj.show();
        } else {
    
            obj.hide();
        }
    
        RP.UI.BubbleLoadComplete();
     
    }
    
    /*
    RP.UI.LoyaltyControlSubmitButton = function(state, func) {
    var obj = $('BtnLoyaltySave');
    
    if (state == "show") {
    obj.show();
    } else {
    obj.hide();
    }
    alert(func);
    obj.onclick = func;
    }
    */
    
    
    RP.UI.LoyaltyControlConfirmation = function(state) {
        var obj = $('loyalty_confirmation');
    
        if (state == "show") {
            obj.show();
        } else {
            obj.hide();
        }
    }
    
    
    RP.UI.LoyaltyControlImage = function(indx, programId, state) {
    
        var imageObj = $('ImgLoyaltyCard');
        if (state == 'show') {
    
            imageObj.src = RP.UI.LoyaltySetImageSrc(indx, programId, 'show');
            imageObj.show();
        } else {
            imageObj.src = RP.UI.LoyaltySetImageSrc('', '', '');
            imageObj.hide();
        }
    }
    
    RP.UI.LoyaltyDoVerify = function() {
    
        var loyaltyNumber = $F('TxtLoyaltyInfo');
        var prox = RP.Util.WebService.Factory("LoyaltyService");
    
        if (_currentLoyaltyProgramId != "" & loyaltyNumber != "") {
    
            prox.GetLoyaltyCardUserName(_currentLoyaltyProgramId, loyaltyNumber, RP.UI.HandleGetLoyaltyVerifyResponse, null);
    
        }
    }
    
    RP.UI.HandleGetLoyaltyVerifyResponse = function(Response) {
        var err = new RP.UI.DisplayError('', 'loyalty_error');
        RP.UI.BubbleLoadComplete();
    
        //turn off error row and message
        err.clear();
        err.display(false);
        if (Response.Status == "Success") {
    
            RP.UI.LoyaltyControlVerify('show', '' + Response.Value + '');
    
        } else {
        err.addMessage(RP.Config.MSG.ERROR_LOYALTY_NUMBER);
            //turn on error
            err.display();
            return false;
        }
    
    }
    
    
    RP.UI.LoyaltyDoSave = function() {
        var err = new RP.UI.DisplayError('', 'loyalty_error');
        err.clear();
        err.display(false);
        var loyaltyNumber = $F('TxtLoyaltyInfo');
        if (loyaltyNumber == "") {
            err.addMessage(RP.Config.MSG.INVALID_LOYALTY_NULL);
            //turn on error
            err.display();
            return false;
    
        } else {
            if (_loyaltyDoVerify == true) { //if this is the first time the user is submitting a number for the card
                RP.UI.BubbleLoadStart();
    
                $RP$CTX.UI.LoyaltyDoVerify();
    
            } else if (_currentLoyaltyOfferId != "" & _currentLoyaltyProgramId != "" & loyaltyNumber != "") {
                RP.UI.BubbleLoadStart();
    
                var ctxObj = { 'OfferId': _currentLoyaltyOfferId, 'ProgramId': _currentLoyaltyProgramId, 'LoyaltyNumber': loyaltyNumber };
                var prox = RP.Util.WebService.Factory("LoyaltyService");
    
                prox.AddUserLoyaltyProgramOffer(_currentLoyaltyOfferId, _currentLoyaltyProgramId, loyaltyNumber, RP.UI.HandleGetLoyaltySaveResponse, null, ctxObj);
    
    
            }
        }
    }
    
    RP.UI.HandleGetLoyaltySaveResponse = function(Response, Context) {
    
        var err = new RP.UI.DisplayError('', 'loyalty_error');
        err.clear();
        err.display(false);
    
        RP.UI.BubbleLoadComplete();
    
    
        if (Response.Status == "Success") {
            RP.UI.LoyaltyControlVerify('hide');
            RP.UI.LoyaltyControlConfirmation('show');
    
            RP.UI.setAlreadySavedState(true);
    
        } else {
    
            //ErrorCode 1 means it's already saved..
            if (Response.ErrorCode == 1) {
                err.addMessage(RP.Config.MSG.ERROR_LOYALTY_ALREADY_SAVED);
            } else {
                err.addMessage(RP.Config.MSG.ERROR_LOYALTY_SAVE);
            }
            //turn on error
            err.display();
            return false;
        }
    }
    
    /* SN - MAY NOT NEED THIS FUNCTION ANYMORE */
    RP.UI.getCookie = function(c_name) {
        if (document.cookie.length > 0) {
            c_start = document.cookie.indexOf(c_name + "=");
            if (c_start != -1) {
                c_start = c_start + c_name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if (c_end == -1) c_end = document.cookie.length;
                return unescape(document.cookie.substring(c_start, c_end));
            }
        }
        return "";
      }
    
    /* BEGIN NEW Clip Print Functions */
      RP.UI.createCookie = function(c_name, value, expiredays) {
        var exdate = new Date();
        var date = new Date();
        date.setTime(date.getTime() + (1000 * 60 * 60 * 24 * 365));
        var expires = "; expires=" + date.toGMTString();
        document.cookie = c_name + "=" + escape(value) + expires + "; path=/";
      }
    
      RP.UI.readCookie = function(c_name) {
        if (document.cookie.length > 0) {
          c_start = document.cookie.indexOf(c_name + "=");
          if (c_start != -1) {
            c_start = c_start + c_name.length + 1;
            c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start, c_end));
          }
        }
        return "";
      }
    
      RP.UI.deleteCookie = function(name, path, domain) {
        var expires = "; expires=Thu, 01-Jan-70 00:00:01 GMT";
        document.cookie = name + "=" + expires + "; path=/";
      }
    
      RP.UI.checkClipPrintCount = function() {
        var str = RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME);
        var countStatus = true;
        if (str) {
          str = str.split(',');
          var strLength = str.length;
    
          if (strLength >= (RP.Config.PRINT.MAXCLIPPED - 1)) {
            alert("You have 'Clipped' the maximum number of offers allowed to print at one time. Please print what you currently have Clipped'.")
            countStatus = false
          }
        }
        return countStatus;
      }
    
      RP.UI.checkClipPrintValue = function(val) {
        var valStatus = false;
    
        if (RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME)) {
          var str = RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME);
          str = str.split(',');
    
    
          for (var i = 0; i < str.length; i++) {
            //alert('string : ' + str[i]);
            //alert('val : ' + val);
            if (str[i] == val) valStatus = true;
            // alert('val status: ' + valStatus);
    
          }
        }
        //alert('val status: ' + valStatus);
        return valStatus;
    
      }
    
      var _clipPrintArray = new Array();
    
      /* This function called on load of page */
      RP.UI.createClipPrintArray = function() {
        if (RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME)) {
    
          var str = RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME);
          //alert("Cookie currently has" + str);
          if (str != "" || str != null) {
            str = str.split(',');
    
            for (j = 0; j < str.length; j++) {
              _clipPrintArray.push(str[j]);
            }
            //alert('clip array: ' + _clipPrintArray);
          }
    
        }
      }
    
      RP.UI.addClipPrintValue = function(val) {
    
        /* if the clippped offer is NOT already on the cookie then add it */
    
        if (!RP.UI.checkClipPrintValue(val)) {
          /*add val to current cookie val*/
          //val = val.replace(/,/ , '|');
          _clipPrintArray.push(val);
          //alert('clip array: ' + _clipPrintArray);
        }
        /*rewrite cookie with current val added to array */
        $RP$CTX.UI.createCookie(RP.Config.CLIP_PRINT_COOKIE_NAME, _clipPrintArray);
        //alert($RP$CTX.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME));
      }
    
      RP.UI.removeClipPrintValue = function(val) {
        /* if the clippped offer is NOT already on the cookie then add it */
    
        if (RP.UI.checkClipPrintValue(val)) {
          //alert('removing: ' + val);
          var j = 0;
    
          while (j < _clipPrintArray.length) {
    
            if (_clipPrintArray[j] == val) {
              /*remove val from current array*/
              _clipPrintArray.splice(j, 1);
              //alert('removing: ' + val);
            } else { j++ }
          }
    
          /*rewrite cookie with current val removed from array */
          $RP$CTX.UI.createCookie(RP.Config.CLIP_PRINT_COOKIE_NAME, _clipPrintArray);
          // alert($RP$CTX.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME));
        }
      }
    
      RP.UI.selectAllOffersInCookie = function(cssClass) {
    
        var obj = document.getElementsByClassName(cssClass);
        if (RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME)) {
          if (obj) {
            if (obj.length > 0) {
              for (i = 0; i < obj.length; i++) {
                /* step through the objects */
                var txtObj = obj[i].next(3);
                var offerVal = obj[i].next(0).value;
    
                offerVal = offerVal.replace(/,/g, '|');
                /* grab just the offerId and offerType(s or n) from the offer str */
                offerVal = offerVal.split('|');
                offerVal = offerVal[0];
                /* compare the offerId of the cookie offer to that of each offer on the page */
                for (j = 0; j < _clipPrintArray.length; j++) {
                  /* grab just the offerId and offerType(s or n) from the offer str */
                  var cookieItem = _clipPrintArray[j].split('|');
    
                  //alert('cookie val : ' + cookieItem[0] + ',offer val: ' + offerVal);
                  if (cookieItem[0] == offerVal) {
                    /* check the checkbox and set the on state for the text */
                    obj[i].down(0).checked = true;
                    txtObj.className = "btn_clipped";
    
                  }
                }
              }
            }
          }
        } else {
          RP.UI.doPrintClippedResetAll();
    
        }
      }
    
    
      /**
      * Visually change the state of the clip icon to be clipped when the HypClip element is clicked
      */
      RP.UI.doClip = function(id) {
        var obj = $(id);
        var chkObj = obj.previous(3).down(0);
        //var offerObj = chkObj.down(1);
        var offerObj = obj.previous(2);
        var val = offerObj.value;
        val = val.replace(/,/g, '|');
        //alert('text val is: ' + val);
        if (RP.UI.checkCookiesAcceptance()) {
          //var txtObj = obj.down(1);
          if (chkObj.checked) {
            chkObj.checked = false;
            obj.className = "btn_clip";
            RP.UI.removeClipPrintValue(val);
          } else {
            /* Check to make sure that the user has not clipped the max number allowed else continue to check if the value already exists */
            if (!RP.UI.checkClipPrintCount()) {
              chkObj.checked = false;
            } else {
    
              chkObj.checked = true;
              obj.className = "btn_clipped";
              RP.UI.addClipPrintValue(val);
            }
          }
        } else {
          $RP$CTX.UI.controlUtility('visible', RP.Config.MSG.SYSTEM_MESSAGING_TITLE_DEFAULT, '', '', '', RP.Config.GLOBAL.SYSTEM_MESSAGING_CONTAINER, 'You need to have cookies enabled to clip coupons.');
          chkObj.checked = false;
        }
      }
    
      /**
      * Visually change the state of the clip icon to be clipped when the ChkClip element is clicked
      *
      */
    
    
    
      RP.UI.doClipBox = function(id) {
        var obj = $(id);
        var txtObj = obj.up(0).next(3);
        var val = obj.up(0).next(0).value;
        //val = val.split(',');
        val = val.replace(/,/g, '|');
        // alert('checkbox val is: ' + val);
        if ($RP$CTX.UI.checkCookiesAcceptance()) {
          if (obj.checked) {
            /* Check to make sure that the user has not clipped the max number allowed else continue to check if the value already exists */
            if (!RP.UI.checkClipPrintCount()) {
              obj.checked = false;
            } else {
    
              //txtObj.update('clipped');
              txtObj.className = "btn_clipped";
              RP.UI.addClipPrintValue(val);
            }
          } else {
            //txtObj.update('clip');
            txtObj.className = "btn_clip";
            RP.UI.removeClipPrintValue(val);
          }
        } else {
          $RP$CTX.UI.controlUtility('visible', RP.Config.MSG.SYSTEM_MESSAGING_TITLE_DEFAULT, '', '', '', RP.Config.GLOBAL.SYSTEM_MESSAGING_CONTAINER, 'You need to have cookies enabled to clip coupons.');
          obj.checked = false;
        }
      }
    
      doCardClip = function(id) {
        var obj = $(id);
        if (obj.className != "btn_card_dimmed") {
    
          var chkObj = obj.previous(0).down(0);
          //var txtObj = obj.down(1);
          if (chkObj.checked) {
            //chkObj.checked = false;
            //obj.update('clip');
            obj.className = "btn_card_clipped";
          } else {
            //chkObj.checked = true;
            //obj.update('clipped');
            obj.className = "btn_card_clip";
          }
        }
      }
    
      /**
      * Visually change the state of the clip icon to be clipped when the ChkClip element is clicked
      *
      */
      doCardClipBox = function(id) {
        var obj = $(id);
        if (obj.className != "btn_card_dimmed") {
    
          var txtObj = obj.up(0).next(0);
    
          if (obj.checked) {
            //txtObj.update('clipped');
            txtObj.className = "btn_card_clipped";
          } else {
            //txtObj.update('clip');
            txtObj.className = "btn_card_clip";
          }
        }
      }
      /**
      * This is used when the 'print all' button is clicked.
      *
      */
      RP.UI.doPrintClipped = function() {
    
        RP.UI.controlClipPrintErrors('hide'); //turn off error display
        RP.UI.controlClipPrintLoading('show'); //turn on loading indication
    
    
        var Spans = $A(document.getElementsByClassName('clip_checkbox_print')); //this class is defined in cb..
        var CardAndMobileSpans = $A(document.getElementsByClassName('clip_checkbox')); //this class is defined in cb..
        var PrintSpans = Spans.findAll(
                          function(s) {
                            var Chk = s.down('input');
    
                            if (Chk.id.indexOf("ChkClipCard") >= 0 ||
                                Chk.id.indexOf("ChkClipMobile") >= 0) {
                              return false;
                            }
                            if (Chk.id.indexOf("ChkClip") >= 0) {
                              return true;
                            }
                            return false;
                          }
                        );
    
        var CardSpans = CardAndMobileSpans.findAll(
                          function(s) {
                            var Chk = s.down('input');
    
                            if (Chk.id.indexOf("ChkClipCard")) {
                              return true;
                            }
                            return false;
                          }
                        )
    
        var Inputs = $A(document.getElementsByTagName("input"));
        var HdnInputs = Inputs.findAll(
                            function(Input) {
                              if (Input.id.indexOf("HdnClipOfferId") > 0)
                                return true;
                              else
                                return false;
                              //return Input.type == "hidden" ? true : false;
                            }
                        );
    
    
        var SecureOfferIds = [];
        var NonSecureOfferIds = [];
        var minChecked = false;
        var ShowClipCardMessage = false;
    
        for (i = 0; i < CardSpans.length; i++) {
          var Chk = CardSpans[i].down('input');
          if (Chk.id.indexOf('ChkClipCard') > 0 && Chk.checked) {
            ShowClipCardMessage = true;
            $(Chk.id).disabled = true;
            continue;
          }
        }
        /* Check to make sure that offers have been clipped to cookie */
        if (RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME)) {
          var CookieVal = RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME);
          var OfferIdArg = "";
          CookieVal = CookieVal.split(",");
          minChecked = true;
    
    
          for (i = 0; i < CookieVal.length; i++) {
            var CookieItem = CookieVal[i];
    
            CookieItem = CookieItem.split('|');
    
            var OfferType = CookieItem[0].substring(0, 1);
            if (OfferType == "s") {
              OfferIdArg = CookieItem[4];
            } else {
              OfferIdArg = CookieItem[0].substring(1);
            }
    
            var offerVendorId = CookieItem[1];
            var offerVendorName = CookieItem[2];
            var isSecure = CookieItem[3];
            if (OfferType == "s") {
              SecureOfferIds.push(OfferIdArg);
            } else {
              NonSecureOfferIds.push(OfferIdArg);
            }
    
    
          }
    
          /* else parse through selected objects as back up */
        } else {
    
          for (i = 0; i < PrintSpans.length; i++) {
            //get the first input descendent
            var Chk = PrintSpans[i].down('input');
    
            if (Chk.checked) {
              minChecked = true;
    
    
              var HdnInputVal = HdnInputs[i].value;
              HdnInputVal = HdnInputVal.split(",");
              var OfferType = HdnInputVal[0].substring(0, 1);
              if (OfferType == "s") {
                var OfferIdArg = HdnInputVal[4];
              } else {
                var OfferIdArg = HdnInputVal[0].substring(1);
              }
    
              var offerVendorId = HdnInputVal[1];
              var offerVendorName = HdnInputVal[2];
              var isSecure = HdnInputVal[3];
              if (OfferType == "s") {
                SecureOfferIds.push(OfferIdArg);
              } else {
                NonSecureOfferIds.push(OfferIdArg);
              }
            }
    
          }
        }
        var url = RP.Config.BASE_URL
        if (SecureOfferIds.size()) {
          url += "Print.aspx?pd=" + RP.Printer.getDeviceId();
          url += '&soffers=' + SecureOfferIds.join(",");
        } else {
          url += "Print.aspx?pd=1";
        }
        if (NonSecureOfferIds.size()) {
          url += '&offers=' + NonSecureOfferIds.join(",");
        }
        if (ShowClipCardMessage) {
          url += '&showcardmessage=1';
        }
        //alert(url);
        //check if something is selected....
    
        RP.UI.controlClipPrintLoading('hide');
    
        if (minChecked) { // at least one item is checked
          RP.UI.controlUtility('visible', 'Printing Offers', '', url);
          // RP.UI.doPrintClippedOmniture();
        } else { // display error
          if (ShowClipCardMessage) {
            url = RP.Config.BASE_URL + 'pages/SaveLoyaltyProgramOfferConfirmation.aspx';
            RP.UI.controlUtility('visible', 'Saving CTC Offers', '', url);
          } else {
            RP.UI.controlClipPrintErrors('show');
          }
        }
    
      }
    
      RP.UI.controlClipPrintErrors = function(state) {
    
        var errorObj = document.getElementsByClassName('homepage_clip_error');
    
        for (i = 0; i < errorObj.length; i++) {
          if (state == 'show') {
            errorObj[i].show();
          } else {
            errorObj[i].hide();
          }
        }
      }
    
      RP.UI.controlClipPrintLoading = function(state) {
    
        var errorObj = document.getElementsByClassName('homepage_clip_loading');
    
        for (i = 0; i < errorObj.length; i++) {
          if (state == 'show') {
            errorObj[i].show();
          } else {
            errorObj[i].hide();
          }
        }
      }
    
    
    
      /* Rules:
      * Send an iteration for each offer to Omniture
      * possibly need to delete cookie from here to make sure it does not get deleted before requests are complete
      */
    
      RP.UI.doPrintClippedOmniture = function(offerType, partnerId, offers) {
    
        var interactionType = 'Print_' + offerType;
        if (partnerId) {
          var partnerIdIndx = partnerId.lastIndexOf("_") + 1;
          var partnerIdLength = partnerId.length;
          partnerId = partnerId.substring(partnerIdIndx, partnerIdLength);
          interactionType = interactionType + "_" + partnerId;
        }
        var offerStr = offers.toString();
        var offerItem = offerStr.split(",");
    
        for (i = 0; i < offerItem.length; i++) {
          //alert("Scott is running a print Omniture Test. OfferID is " + offerItem[i]);
          RP.Tracking.setInteraction(this, offerItem[i], interactionType, '', '', '', 'true')
        }
      }
    
    
    
      RP.UI.doPrintClippedResetAll = function() {
    
        var Spans = document.getElementsByClassName('clip_checkbox_print');
        var Inputs = document.getElementsByTagName("input");
    
        for (i = 0; i < Spans.length; i++) {
          //get the first input descendent
          var Chk = Spans[i].down('input');
          var ChkLabel = Spans[i].next(3)
          if (Chk.checked) {
            RP.UI.doClip(ChkLabel.id);
            RP.UI.doClipBox(Chk.id);
          }
        }
    
        if (RP.UI.readCookie(RP.Config.CLIP_PRINT_COOKIE_NAME)) {
          RP.UI.deleteCookie(RP.Config.CLIP_PRINT_COOKIE_NAME);
        }
      }
    
      /* END NEW Clip Print Functions */
    
    
    /**
    * Handles error display..
    *
    * @author Mandarin Drummond
    */
    RP.UI.DisplayError = Class.create();
    
    Object.extend(RP.UI.DisplayError.prototype, {
    
        _msgs: [],
        _displayContainer: RP.Config.CSS.UI_ERR_DIV,
    
        /**
        * Class constructor
        */
        initialize: function(msg, id) {
    
            if (id) {
                this.setDisplayContainer(id);
            }
            if (msg) {
                this.addMessage(msg);
            }
        },
    
        /**
        * Add an error message to the object internal error collection
        */
        addMessage: function(msg) {
    
            this._msgs.push(msg);
    
        },
    
        /**
        * Retrieve all existing errors in the object
        */
        getMessages: function() {
    
            return this._msgs;
        },
    
        /**
        * Determines if there are errors..
        */
        hasErrors: function() {
    
            return this._msgs.size() ? true : false;
    
        },
    
        /**
        * Display errors to the screen
        */
        display: function(show) {
    
            if (show === false) {
                $(this._displayContainer).hide();
                return;
            }
    
            if (this.hasErrors()) {
                $(this._displayContainer).show();
                $(this._displayContainer).update(this.getMessages().join("<br/>"));
            }
        },
    
        hide: function() {
            $(this._displayContainer).hide();
        },
    
        /**
        * Set the DOM element used for display of errors
        */
        setDisplayContainer: function(id) {
            this._displayContainer = id;
        },
    
        /**
        * Purge errors in the objects internal error collection
        */
        clear: function() {
    
            this._msgs = [];
    
        }
    
    });
    
    
    //Object.extend(RP.UI.DisplayError.prototype, RP.UI.DisplayError);
    
    var $RP$ERR = new RP.UI.DisplayError();
    
    
    /** end ui.class.js code */
    
    /** 02182008 SN - coded ported from uitl.class.js */
    
    /**
    * Utility methods and classes
    *
    * @author Mandarin Drummond
    * @author Scott Noring
    */
    RP.Util = {}
    
    RP.Util.Object = {};
    RP.Util.Object.deepCopy = function(obj) {
        var nobj = new Object();
        for (var prop in obj) {
            nobj[prop] = obj[prop];
        }
        return nobj;
    }
    
    /**
    * Random methods
    *
    */
    
    RP.Util.String = {};
    
    /**
    * Trims leading zeros
    */
    RP.Util.String.ltrimZeros = function(str) {
    
        var nstr = str.replace(/^[0]+/g, "");
    
        return nstr;
    
    }
    
    /**
    * Makes a string safe for javascript and HTML attribute values
    */
    RP.Util.String.escapeQuotes = function(str) {
        if (!str) return str;
    
        return str.gsub("'", "\\'").gsub('"', "&quot;")
    }
    
    RP.Util.String.toDateString = function(dt) {
        var dateStr = '';
        if (dt && dt > 0) {
            var dtobj = new Date(dt);
            var dateStr = (dtobj.getMonth() + 1) + "/" + dtobj.getDate() + "/" + dtobj.getFullYear();
        }
        return dateStr;
    }
    
    RP.Util.String.isEmpty = function(source) {
        source = source ? source : this;
        if (source &&
            source != null &&
            source != "null" &&
            source != undefined &&
            source != "undefined") {
            return false;
        }
        return true;
    
    }
    
    Object.extend(String.prototype, RP.Util.String);
    
    /**************************************************
    * [BEGIN] Global variable routines
    *
    * @author Mandarin Drummond
    */
    
    //create the global namespace
    eval('document.' + RP.Config.GLOBAL.NS + ' = {};');
    
    /**
    * Set a global variable
    *
    * @param string name   variable name
    * @param mixed  value  value of variable
    * @param string ns     optional namespace argument (default in RP.Config.GLOBAL.NS)
    */
    RP.Util.setGlobal = function(name, value, ns) {
    
      //ns isn't the default
      if (ns && ns != RP.Config.GLOBAL.NS && !RP.Util.getGlobal(ns)) {
        RP.Util.setGlobal(ns, {});
      }
    
      //alert('document.' + (ns !== undefined ? RP.Config.GLOBAL.NS + '.' + ns : RP.Config.GLOBAL.NS) + '.' + name + ' = value;');
      eval('document.' + (ns !== undefined ? RP.Config.GLOBAL.NS + '.' + ns : RP.Config.GLOBAL.NS) + '.' + name + ' = value;');
    }
    
    /**
    * Get a global variable
    *
    * @param string name   variable name
    * @param string ns     optional namespace argument (default in RP.Config.GLOBAL.NS)
    */
    RP.Util.getGlobal = function(name, ns) {
        //alert('var str = document.' + (ns !== undefined ? RP.Config.GLOBAL.NS + '.' + ns : RP.Config.GLOBAL.NS) + '.' + name + ';');
        eval('var str = document.' + (ns !== undefined ? RP.Config.GLOBAL.NS + '.' + ns : RP.Config.GLOBAL.NS) + '.' + name + ';');
        return str;
    }
    
    /**
    * get all the globals in a namespace
    *
    * @param string ns
    * @return object hashmap of globals..
    */
    RP.Util.getGlobals = function(ns) {
        return RP.Util.getGlobal((ns !== undefined ? ns : RP.Config.GLOBAL.NS));
    }
    
    /**
    * Alias to RP.Util.getGlobal
    *
    * @param string name
    * @return mixed
    */
    $RP = function(name) {
        return RP.Util.getGlobal(name);
    }
    
    /**
    * Increment a global variable
    *
    * @param string name   variable name
    * @param string ns     optional namespace argument (default in RP.Config.GLOBAL.NS)
    */
    RP.Util.incGlobal = function(name, ns) {
        eval('document.' + (ns !== undefined ? ns : RP.Config.GLOBAL.NS) + '.' + name + '++;');
    }
    
    /**
    * Increment a global variable
    *
    * @param string name   variable name
    * @param string ns     optional namespace argument (default in RP.Config.GLOBAL.NS)
    */
    RP.Util.decGlobal = function(name, ns) {
        eval('document.' + (ns !== undefined ? ns : RP.Config.GLOBAL.NS) + '.' + name + '--;');
    }
    
    var $RP$CACHEEXP = [];
    
    RP.Util.setCache = function(name, value, lifetime, ns) {
        //set global
        lifetime = lifetime ? lifetime : RP.Config.CACHE.LIFETIME;
        var dt = new Date();
        //alert(dt.getTime() + " " + fdt.getTime());
        var key = ns ? name + '_' + ns : name;
        $RP$CACHEEXP[key] = dt.getTime() + (lifetime * 1000);
        RP.Util.setGlobal(name, value, ns);
    }
    
    RP.Util.getCache = function(name, ns) {
        var key = ns ? name + '_' + ns : name;
        //check lifetime
        if ($RP$CACHEEXP[key]) {
            var dt = new Date();
            var cdt = new Date($RP$CACHEEXP[key]);
            if (cdt.getTime() > dt.getTime()) {
                return RP.Util.getGlobal(name, ns);
            }
        }
        return false;
    }
    
    
    $RP$CACHE = function(name, ns) {
        return RP.Util.getCache(name, ns);
    }
    /*
    * [END] Global variable routines
    **************************************************/
    
    
    /**
    * [BEGIN] General web service routines
    */
    
    RP.Util.WebService = {}
    RP.Util.WebService.Factory = function(wsName) {
    
        if (RP.Util.getGlobal(wsName + 'Proxy') == undefined) {
            var nsPrefix = "Valassis.RedPlum.Web.FrameComponents.Web.Services.";
    
            try {
                eval("var ws = new " + nsPrefix + wsName + "();");
            } catch (e) {
                alert("No such web service '" + wsName + "'. Is it declared in your ScriptManager?");
            }
    
    
            ws.set_defaultFailedCallback(function(error) {
    
                /**
                * MD 10/11/2007 - Scott N:
                *
                * These things are available to you, but I think really we just need these
                * for debugging. When we go live it should just say something like: 
                * "There was an error with the request...or something generic."
                */
    
                //    var stackTrace = error.get_stackTrace();
                //    var message = error.get_message();
                //    var statusCode = error.get_statusCode();
                //    var exceptionType = error.get_exceptionType();
                //    var timedout = error.get_timedOut();
    
    
                RP.UI.controlUtility('visible', RP.Config.MSG.SYSTEM_MESSAGING_TITLE_DEFAULT, '', '', '', RP.Config.GLOBAL.SYSTEM_MESSAGING_CONTAINER, RP.Config.MSG.SYSTEM_MESSAGING_COPY_DEFAULT);
    
            });
    
            RP.Util.setGlobal(wsName + 'Proxy', ws);
        }
    
        return RP.Util.getGlobal(wsName + 'Proxy');
    }
    
    /**
    * [END] General web service routines
    */
    
    /**************************************************
    * [BEGIN] Exception class
    */
    
    /**
    * RP Exception handler
    *
    * @author Mandarin Drummond
    */
    RP.Util.Exception = Class.create();
    
    Object.extend(RP.Util.Exception, Error);
    
    Object.extend(RP.Util.Exception.prototype, {
    
    
        initialize: function(mesg) {
    
            this.message = mesg;
        },
    
        alert: function(mesg) {
    
            /**
            * For now just throw a native alert() up, but later
            * we can customize this to be a bit more graceful.
            */
            alert(mesg ? mesg : this.message);
    
        }
    
    
    });
    
    //alias
    $RP$EX = RP.Util.Exception;
    
    /**
    * [END] Exception class
    **************************************************/
    
    
    
    /***************************************************
    * [BEGIN] Cookie class
    */
    
    
    /**
    * Cookie wrapper - extends a 3rd party lib (currently) - see lib/cookies.js
    *
    * @author Mandarin Drummond
    *
    */
    RP.Util.Cookie = Class.create();
    
    Object.extend(RP.Util.Cookie.prototype, new CookieJar);
    
    RP.Util.Cookie.appendString = RP.Config.GLOBAL.NS + "_";
    
    RP.Util.Cookie.options = {
        expires: RP.Config.COOKIE.LIFETIME, 	// seconds 
        path: '', 		// cookie path
        domain: '', 		// cookie domain
        secure: ''			// secure ?
    };
    
    /**
    * [END] Cookie class
    **************************************************/
    
    /**************************************************
    * [BEGIN] Persister functionality
    */
    
    /**
    * The persister class abstracts the details of how user variables (preferences, UI 
    * state, etc) are stored from the rest of the RP client-side API. Non registered 
    * users will rely on cookies for persistence of variables, while registered users
    * may need to store information in cookies AND server-side. 
    *
    * @author Mandarin Drummond
    *
    */
    RP.Util.Persistent = Class.create();
    
    Object.extend(RP.Util.Persistent, {
    
        /**
        * Get a persistent variable
        *
        * @param   string   name
        * @return  mixed
        */
        get: function(name) {
    
            //get from cookies 
            var ck = new RP.Util.Cookie(RP.Util.Cookie.options);
            return ck.get(name);
    
        },
    
        /**
        * Set a persistent variable
        *
        * @param   string    name
        * @param   mixed     value
        * @return  boolean
        */
        set: function(name, value) {
    
            var ck = new RP.Util.Cookie(RP.Util.Cookie.options);
    
            //store cookie    
            return ck.put(name, value);
    
        },
    
        /**
        * Remove a persistent variable
        *
        * @param   string  name 
        * @return  boolean
        */
        destroy: function(name) {
    
    
            var ck = new RP.Util.Cookie(RP.Util.Cookie.options);
    
            //remove cookie var
            return ck.remove(name);
    
        },
    
        /**
        * Condense an object into a space-saving
        * serialized format.
        *
        * @param   object  obj         object to condense
        * @param   array   properties  list of properties to include
        * @return  string  
        */
        condense: function(obj, properties, delim) {
    
            var obj_props = new Array();
    
            properties.each(
    
                function(prop, indx) {
                    obj_props[indx] = obj[prop];
    
                }
    
            );
    
            var objstr = obj_props.join(delim ? delim : RP.Config.COOKIE.DELIM);
    
            return objstr;
    
        },
    
        /**
        * Expand a serialized/condensed object
        *
        * @param   string sobj   serizalized object
        * @return  object
        */
        expand: function(sobj, properties, delim) {
    
            if (!sobj) {
                throw new $RP$EX("Variable to expand is empty.");
            }
    
            var arr = sobj.split(delim ? delim : RP.Config.COOKIE.DELIM);
    
            var obj = new Array();
    
            properties.each(
    
                function(prop, indx) {
    
                    obj[prop] = arr[indx];
    
                }
    
            );
    
            return obj;
    
        }
    
    });
    
    RP.Util.Printable = Class.create();
    
    Object.extend(RP.Util.Printable.prototype, {
    
        /**
        * Constructor expects a valid Id of an iframe
        *
        *
        */
        initialize: function(elem_id) {
    
            this._printWindow = window.frames[elem_id];
            //alert(this._printWindow);
        },
    
        print: function() {
    
            this._printWindow.focus();
            this._printWindow.print();
    
        }
    
    });
    
    
    /******************************************************
    * [BEGIN] User agent/browser wrapper
    */
    
    /**
    * Gets the client platform/browser info
    *
    * @author Mandarin Drummond
    */
    
    RP.Util.UserAgent = {
    
        getPlatform: function() {
    
            return navigator.platform;
    
        },
    
        getBrowserName: function() {
    
            return navigator.appName;
    
        },
    
        getBrowserMajorVersion: function() {
    
            return parseInt(navigator.appVersion);
    
        },
    
        getBrowserMinorVersion: function() {
    
            return '0';
    
        }
    
    }
    
    /*
    * [END] User agent/browser wrapper
    ******************************************************/
    
    //RP.Util.Refreshable = Class.create();
    
    //Object.extend(RP.Util.Refreshable.prototype, {
    
    //    /**
    //     * This method refreshes all registered responders in the this._refreshResponder collection. 
    //     * The method is designed to refresh content within the widget after user settings or options have changed,
    //     * without reloading the widget entirely. 
    //     *
    //     * @return null
    //     */
    //    refreshData : function() {
    //    
    //        if (!this._refreshables)
    //            return;
    //    
    //        this._refreshables.each(
    //            function(func, indx) {
    //                func();
    //            }
    //        );
    //    
    //    },
    //    
    //    /**
    //     * Use this to register refreshable methods
    //     *
    //     *
    //     */
    //    registerRefreshable : function(func) {
    //    
    //        if (!this._refreshables) {
    //            this._refreshables = new Array();
    //        }
    //        
    //        this._refreshables.push(func);
    //    
    //    },
    //    
    //    clearRefreshables : function() {
    //        this._refreshables = new Array();
    //    }
    
    //});
    
    ///******************************************************
    // * [BEGIN] Various utility methods
    // */
    
    ///**
    // * Get a unique document element ID
    // *
    // * @param string optional prefix prefix of the ID
    // * @return string id
    // */
    //RP.Util.getUniqueDomId = function(prefix, 
    //							   suffix) {
    
    //	prefix = prefix == undefined ? '_' : prefix;
    //	suffix = suffix == undefined ? '_' : suffix;
    
    //	var cnt = 0;
    //	var id;
    //	do { 
    //		id = prefix + suffix + cnt; 
    //		cnt++;
    //	} while ($(id) != null);
    
    //	return id;
    //}
    
    ///**
    // * Have no idea what this is for..
    // *
    // */
    //RP.Util.captureEvents = function() {
    //    return false;
    //}
    
    ///**
    // * Gets the highest z-index in a div
    // *
    // * @param string container div/element
    // * @return integer
    // */
    //RP.Util.getTopZ = function(container) {
    //	return $(container).topZ;
    //}
    
    ///**
    // * Increases the highest z-index
    // *
    // * @param string container div/element
    // */
    //RP.Util.bumpTopZ = function(container) {
    //	
    //	if ($(container) == null) {
    //	    throw $RP$EX("Unable to increment z-index: container is not defined.");
    //		//throw new Error();
    //		return false;
    //	}
    //	
    //	if ($(container).topZ == undefined) {
    //		$(container).topZ = 0;
    //	}
    //	
    //	$(container).topZ++;
    //}
    
    
    
    /** The functions below will neeed the RP.UI namespace.
    * SN 031108 - I could not get RP.UI to work for an unknown reason. I had this inserted up within the existing RP.UI methods
    */
    
    
    
    setRateOverState = function(obj, val) {
        clearTimeout(_rateTimer);
        _rateObj = $("img_" + obj);
        _rateObj.src = _rateImagePath + "_" + 0 + "_" + val + "0.gif";
    }
    
    setRateTimer = function(whichStyle, rateObjValue) {
        _rateTimer = setTimeout("setRateOutState('" + whichStyle + "','" + rateObjValue + "')", 100);
    }
    
    setRateOutState = function(whichStyle, rateObjValue) {
        clearTimeout(_rateTimer);
        _rateObj.src = _rateImagePath + "_0_" + rateObjValue + "0.gif";
    }
    
    
     
    
     
     

