﻿/**
 * Handles user persistent data, authentication, and other related tasks
 *
 * @author Mandarin Drummond
 */
RP.User = Class.create();
RP.User = {

    /**
     * Initialize the user..
     *
     *
     *
     */
    init : function() {
    
      //get all persistent attributes necessary into local variables...
    
        var attrs = RP.Util.Persistent.get('RPUSR');
        
        attrs.each(
            
            function (pair) {
            
                RP.Util.setGlobal(pair.key, pair.value, 'RPUSR');
            }
        
        );
    
    },
    
    _getCookieNamespace : function(ns) {
    
        ns = ns ? RP.Config.USER.USERCK + '_' + ns : RP.Config.USER.USERCK;
    
        return ns;
    },
    
    getUser : function(callBack) {
        //check for cache
        var resp = RP.Util.getCache('user');
        if (resp) {
            if (callBack) {
                callBack(resp.User);
                return resp.User;
            }
            return resp.User;
        }
        //get from server
        var prox = RP.Util.WebService.Factory("UserService");
        if (!callBack) {
            var UseThisCallBack = function(resp) {
                RP.Util.setCache('user', resp);
            }
        } else {
            var UseThisCallBack = function(resp) {
                callBack(resp);
                RP.Util.setCache('user', resp);
            }
        }
        //call web service..
        prox.GetUser(callBack);
    },
    
    /**
     *
     * @param string ns optional namespace
     *
     */
    getAttributes : function(ns) {
        
        ns = RP.User._getCookieNamespace(ns);
        
        var ret = RP.Util.getGlobals(ns);

        if (ret == undefined) {
            //check for persistent??
            
        }
        
        return ret;
    },
    
    removeAttribute : function(name, ns) {
        ns = RP.User._getCookieNamespace(ns);
        var attrs = RP.Util.Persistent.get(ns);
        
        eval("attrs." + name + " = undefined;");
        
        RP.Util.Persistent.destroy(ns);
        RP.Util.setGlobal(name, undefined, ns);
    },

    /**
     * Get a user setting/attribute. Example would be zip code.
     *
     * @param string    name
     * @param string    ns  optional namespace
     * @return mixed
     */
    getAttribute : function(name, ns) {
        
        ns = RP.User._getCookieNamespace(ns);
         
        try
        {
          //check for persistent??
            var attrs = RP.Util.Persistent.get(ns);
            eval("ret = attrs." + name + ";");
            RP.Util.setGlobal(name, ret, ns);
        }
        catch(e)
        {
            //ignore - return failure
        }
    
        if (ret == undefined) {
            //get from globals
            try {
                var ret = RP.Util.getGlobal(name, ns);
            } 
            catch (e) 
            {
                //ignore - try persistent
            }
        }
        return ret;
    },
    
    /**
     * Set a user setting/attribute. Example would be zip code.
     *
     * @param string    name
     * @param mixed     val
     * @param string    ns  optional namespace
     */
    setAttribute : function(name, val, ns) {
    
        ns = RP.User._getCookieNamespace(ns);
        //set in globals
        RP.Util.setGlobal(name, val, ns);
    
        var attrs = RP.Util.Persistent.get(ns);
        
        attrs = attrs ? attrs : {};
        
        eval("attrs." + name + " = val;");
    
        return RP.Util.Persistent.set(ns, attrs);   
    
    },
    
    /**
     * Determine if a user is authenticated.
     *
     *
     *
     */
    isAuthenticated : function(serverCheck, successCallback, failureCallback) {
    
        if (serverCheck) {
            var prox = RP.Util.WebService.Factory("AuthService");
            prox.IsAuthenticated(successCallback, failureCallback);        
        } else {
            if (RP.Util.Persistent.get(RP.Config.USER.UIDCK)) {
                return true;
            }
            
            return false;
        }    
    
    },
    
    /**
     * Authenticate a user
     *
     *
     *
     */
    authenticate : function(email, pass, successCallback, failureCallback) {
    
        //authenticate via web service.
        var prox = RP.Util.WebService.Factory("AuthService");
        prox.Login(email, pass, successCallback, failureCallback);
        
    },
    
    login : RP.User.authenticate,
    
    /**
     * Log a user out
     *
     * @author Mandarin Drummond
     *
     * @param function successCallback   required callback function reference that handles a successful web service request 
     *                                   (but not necessarily a successful logout!)
     * @param function failuresCallback  required callback function reference that handles a failed web service request
     * @return null
     */
    logout : function(successCallback, failureCallback) {

        if (typeof(successCallback) != 'function' ||
            typeof(failureCallback) != 'function') {
            throw new $RP$EX('Invalid arguments.');
        }
        //authenticate via web service.
        var prox = RP.Util.WebService.Factory("AuthService");
        prox.Logout(successCallback, failureCallback);
    }

};

//alias
$RP$USR = function (name, ns) {
    return RP.User.getAttribute(name, ns);
}

RP.User.Location = Class.create();

Object.extend(RP.User.Location.prototype, {

    /** 
     * Returns the users zip. If the namespace is provided, we try to find a zip
     * for that namespace first...then check for a global one.
     *
     * @param string widgetType optional namespace...allows the user to have zips set for different content
     */
    getZipCode : function(widgetType) {
        var attr = widgetType ? (RP.Config.USER.ATTR.ZIP + '_' + widgetType) : RP.Config.USER.ATTR.ZIP;
        var ret = RP.User.getAttribute(attr);
//        alert(widgetType);
//        alert(ret);
        return ret ? ret : RP.User.getAttribute(RP.Config.USER.ATTR.ZIP);
    },  
    
    /**
     * Returns the users location radius in miles
     *
     * @param string widgetType optional widget type/namespace
     */
    getRadius : function(widgetType) {
        var attr = widgetType ? (RP.Config.USER.ATTR.LOC_RAD + '_' + widgetType) : RP.Config.USER.ATTR.LOC_RAD;
        var ret = RP.User.getAttribute(attr);
        return ret ? ret : RP.User.getAttribute(RP.Config.USER.ATTR.LOC_RAD);
    },
    
    getLatitude : function(widgetType) {
        var attr = widgetType ? (RP.Config.USER.ATTR.LOC_LAT + '_' + widgetType) : RP.Config.USER.ATTR.LOC_LAT;
        var ret = RP.User.getAttribute(attr);
        return ret ? ret : RP.User.getAttribute(RP.Config.USER.ATTR.LOC_LAT);
    },
    
    getLongitude : function(widgetType) {
        var attr = widgetType ? (RP.Config.USER.ATTR.LOC_LON + '_' + widgetType) : RP.Config.USER.ATTR.LOC_LON;
        var ret = RP.User.getAttribute(attr);
        return ret ? ret : RP.User.getAttribute(RP.Config.USER.ATTR.LOC_LON);
    },
    
    /**
     * Returns a location object of type Valassis.Location.location (see the Valassis.Location class lib).
     * NOTE: this function won't return anything if no zip has been set for the user (first time user or cleared cookies)
     * so be sure to accomodate this.
     *
     * @param string widgetType optional widgetType
     * @return Valassis.Location.location
     */
    getLocation : function(widgetType, callBack) {
    
        var getGlobal = function() {
            if (widgetType) {
                try {
                    var loc = RP.Util.getGlobal('loc', widgetType)
                } catch (e) {
                    var loc = $RP('loc');
                }
            } else {
                var loc = $RP('loc');
            }
            return loc;        
        }
        
        var loc = getGlobal();
        //var loc = widgetType ? RP.Util.getGlobal('loc', widgetType) : $RP('loc');
        if (!loc) {
            RP.User.Location.setLocation(widgetType, callBack)
        } else {
        
            if (callBack) {
                callBack();
            } else {
                return getGlobal();
            }
        }
    },

    /**
     * NOTE: this function won't return anything if no zip has been set for the user (first time user or cleared cookies)
     * so be sure to accomodate this.    
     */
    setLocation : function(widgetType, callBack) {
    
        var zip = RP.User.Location.getZipCode(widgetType);
    
        var callBackMajor = function(resp) {
            if (widgetType) {
                RP.Util.setGlobal('loc', resp.Location, widgetType);
            } else {
                RP.Util.setGlobal('loc', resp.Location);
            }
            if (callBack) {
                callBack();
            }
        }
        
        var locws = RP.Util.WebService.Factory('LocationService');
        
        if (!zip) {
            var resp = {};
            resp.Status = "Failure";
            resp.Message = "No zip code set.";
            callBackMajor(resp);
            return;
        }
        
        locws.GetLocationByZip(zip, callBackMajor);
    },
    
    getCityState : function(widgetType) {
    
    },
    
    /**
     * Sets the location for a widget type
     *
     * @param string    widgetType      type of widget, "Local Deals", "Grocery", etc. This might become an Id later instead of a name
     * @param string    zipCode         zip code to be used as the center point
     * @param string    radius          radius (ex: 5, 10, 50) in miles
     * @param boolean   clientSideOnly  whether or not to store on the server side
     */
    setPlumTypeScope : function(widgetType, zipCode, radius, clientSideOnly, succCallBack, failureCallBack) {

        function wsSuccCallBack(resp) {
        
            if (resp.Status === "Success") {
        
                //use RP.Config.USER.ATTR.LOC_COORD
                //set globals for the widget
                
                RP.Util.setGlobal('loc', resp.Location, widgetType);     
                if (!clientSideOnly && RP.User.isAuthenticated()) {
                    var ws = RP.Util.WebService.Factory('UserService');
                    ws.SetWidgetLocationScope(widgetType, resp.Location.ZipCode, radius)
                }
                
                //set location properties
                RP.User.setAttribute(RP.Config.USER.ATTR.ZIP     + '_' + widgetType, resp.Location.ZipCode);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_RAD + '_' + widgetType, radius);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_LAT + '_' + widgetType, resp.Location.Coordinate.Latitude);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_LON + '_' + widgetType, resp.Location.Coordinate.Longitude);
                
                succCallBack();
                
            } else {
                failureCallBack();
            }

        }
        //get location
        var locws = RP.Util.WebService.Factory('LocationService');
        locws.GetLocationByZip(zipCode, wsSuccCallBack, failureCallBack);
    
    },
    
    //client side only for now
    removePlumTypeScope : function(widgetType) {
        try {
            RP.User.removeAttribute(RP.Config.USER.ATTR.ZIP    + '_' + widgetType);
            RP.User.removeAttribute(RP.Config.USER.ATTR.LOC_RAD + '_' + widgetType);
            RP.User.removeAttribute(RP.Config.USER.ATTR.LOC_LAT + '_' + widgetType);
            RP.User.removeAttribute(RP.Config.USER.ATTR.LOC_LON + '_' + widgetType);
        } catch (e) {
            //debug
            //alert("error removing scope");        
        }
    },
    
    getPlumTypeScope : function(widgetType, clientSideOnly) {
    
    }, 
    
    /**
     * Sets the location for a user.
     *
     * @param string    zipCode         zip code to be used as the center point
     * @param string    radius          radius (ex: 5, 10, 50) in miles
     * @param boolean   clientSideOnly  whether or not to store on the server side
     */
    setGlobalScope : function(zipCode, radius, clientSideOnly, succCallBack, failureCallBack) {

        succCallBack  = succCallBack ? succCallBack : function(){};
        failureCallBack  = failureCallBack ? failureCallBack : function(){};

        function wsSuccCallBack(resp) {
        
            if (resp.Status = "Success") {
            
                RP.Util.setGlobal('loc', resp.Location);
                
                if (!clientSideOnly && RP.User.isAuthenticated()) {
                    var ws = RP.Util.WebService.Factory('UserService');
                    ws.SetLocationScope(resp.Location.ZipCode, radius)
                }

                RP.User.setAttribute(RP.Config.USER.ATTR.ZIP, resp.Location.ZipCode);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_RAD, radius);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_LAT, resp.Location.Coordinate.Latitude);
                RP.User.setAttribute(RP.Config.USER.ATTR.LOC_LON, resp.Location.Coordinate.Longitude);
               
                succCallBack();
            } else {
                failureCallBack(resp);
            }
            
        }
        
        
        //get location
        var locws = RP.Util.WebService.Factory('LocationService');
        locws.GetLocationByZip(zipCode, wsSuccCallBack);
    
    }

});

Object.extend(RP.User.Location, RP.User.Location.prototype);

RP.User.Content = Class.create();

/**
 * Gets from cookies only!
 *
 */
RP.User.Content.GetSavedOfferCount = function() {

    var existing = RP.Util.Persistent.get("RPOFR");
    if (existing) {
        return existing.size();
    } else {
        return '0';
    }
}

/**
 * Get the saved offers...by default it stores the ids in cookies
 *
 */
RP.User.Content.GetSavedOffers = function(afterFinish) {
    var ws = RP.Util.WebService.Factory('OfferService');
    if (typeof(afterFinish) != "function") {
        var afterFinish = function(resp) {
            if (resp.Status == "Success") {
                var ids = [];
                resp.Offers.each(
                    function(ofr, indx) {
                        ids.push(ofr.OfferId);
                    }
                );

                RP.Util.Persistent.set("RPOFR", ids.uniq());            
            } else {
                throw new $RP$EX("Failed to fetch offers: " + resp.Message);
            }
        }
    }
    ws.GetFavorites(0, 0, 0, afterFinish);

}

RP.User.Content.AddSavedOffers = function(OfferIds, CallBack) {

    if (!OfferIds || !OfferIds.size()) {
        throw new $RP$EX("Invalid arguments. Array of Offer Ids expected.");
    }
    
//    var existing = RP.Util.Persistent.get("RPOFR");
//    existing = existing == null ? [] : existing;
//    //existing = $A(existing); 
//    var ids = OfferIds;
//    if (existing.size()) {
//        //var ids = Array.concat([1,2], [5,6]);
//        var ids = existing.concat(OfferIds);
//    }
//    RP.Util.Persistent.set("RPOFR", ids.uniq());    

    if (!CallBack) {
        CallBack = function(resp) { alert(resp.Message); }
    }

    if (RP.User.isAuthenticated() || true) {
        var ws = RP.Util.WebService.Factory('OfferService');
        ws.AddFavorites(OfferIds, CallBack);
    } else {
        var resp = {"Status" : "Success"};
        CallBack(resp);
    }
}
/**
 * 
 * @param array     OfferIds    array of offerIds
 * @param function  CallBack    function that takes one argument (resp, which is a response object)
 *
 */
RP.User.Content.RemoveSavedOffers = function(OfferIds, CallBack) {

    if (!OfferIds || !OfferIds.size()) {
        throw new $RP$EX("Invalid arguments. Array of Offer Ids expected.");
    }
    //storing in cookies
    var existing = RP.Util.Persistent.get("RPOFR");
    if (existing) {
        OfferIds.each(
            function(ofrId, indx) {
                var fndIndx = existing.indexOf(ofrId);
                if (fndIndx >= 0) {
                    existing[fndIndx] = null;
                }
            }
        );

        RP.Util.Persistent.set("RPOFR", existing.compact());
    }

    if (RP.User.isAuthenticated()) {
        var ws = RP.Util.WebService.Factory('OfferService');

        if (!CallBack) {
            CallBack = function(resp) { alert(resp.Message); }
        }
        ws.RemoveFavorites(OfferIds, CallBack);
    } else {
        if (CallBack) {
            var resp = {Status : "Success"}
            CallBack(resp);
        }
    }

}

