var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/// <reference path="../env/SessionStorage.ts" />
/// <reference path="history/VisitorHistory.ts" />
/// <reference path="visitor/VisitorData.ts" />
/// <reference path="visitor/IVisitorDataConfigOptions.ts" />
/// <reference path="../util/ArrayUtils.ts" />
/// <reference path="../cookie/Store.ts" />
/// <reference path="../tracking/VisitorId.ts" />
/// <reference path="../env/Session.ts" />
var econda;
(function (econda) {
    var recengine;
    (function (recengine) {
        var VisitorHistory = econda.recengine.history.VisitorHistory;
        var VisitorData = econda.recengine.visitor.VisitorData;
        var ArrayUtils = econda.util.ArrayUtils;
        var VisitorId = econda.tracking.VisitorId;
        var SessionStorage = econda.env.SessionStorage;
        var Session = econda.env.Session;
        /**
         * Represents a visitor profile. {@link econda.data#visitor} contains the profile of current visitor.
         *
         * <h3>Examples</h3>
         * Do login current visitor
         *     econda.data.visitor.login({
         *       ids: { customerId: 'the customer id' }
         *     });
         *
         * Do logout current visitor
         *     econda.data.visitor.logout();
         *
         * Set properties during login
         *     econda.data.visitor.login({
         *       ids: { customerId: 'the customer id' },
         *       properties: { 'gender', 'm' } // properties must be configured on server side to
         *     });
         *
         * Set properties without doing a login
         *     econda.data.visitor.setProperty('gender', 'm');
         *
         * Get a list of "product:view" events
         *     var viewEvents = econda.data.visitor.getHistory().getFilteredItems(function(i){ return i.getType() === 'product:view' });
         *
         * @class econda.recengine.VisitorProfile
         */
        var VisitorProfile = (function (_super) {
            __extends(VisitorProfile, _super);
            function VisitorProfile(cfg) {
                if (cfg === void 0) { cfg = null; }
                _super.call(this);
                /**
                 * @private
                 * @property {econda.recengine.visitor.VisitorData} _persistentData Data to be stored in session storage
                 */
                this._persistentData = null;
                this.initConfig(cfg);
                this._initPersistentData();
                var storageKey = 'econda.recengine.VisitorProfile.initialized';
                if (SessionStorage.getItem(storageKey) === null) {
                    this._onFirstInitOfSession();
                }
                SessionStorage.setItem(storageKey, (new Date()).toString());
                this._initRecipientId();
            }
            /**
             * Do not save changes until we call commitTransaction manually
             * @method
             */
            VisitorProfile.prototype.beginTransaction = function () {
                this._persistentData.beginTransaction();
            };
            /**
             * Save all changes (from last transaction)
             * @method
             */
            VisitorProfile.prototype.commitTransaction = function () {
                this._persistentData.commitTransaction();
            };
            /**
             * Get econda visitor id from cookie
             * @method
             */
            VisitorProfile.prototype.getVisitorId = function () {
                return VisitorId.get();
            };
            /**
             * Get econda session id from cookie
             * @method
             */
            VisitorProfile.prototype.getSessionId = function () {
                return Session.getId();
            };
            /**
             * Visitors recipient id (mailing user reference)
             * @cfg {String} recipientId
             * @accessor
             */
            VisitorProfile.prototype.getRecipientId = function () {
                return this._persistentData.getId('recipientId');
            };
            VisitorProfile.prototype.setRecipientId = function (recipientId) {
                this._persistentData.setId('recipientId', recipientId);
            };
            /**
             * Visitors customer id (crm customer id)
             * @cfg {String} customerId
             * @accessor
             */
            VisitorProfile.prototype.getCustomerId = function () {
                return this._persistentData.getId('customerId');
            };
            VisitorProfile.prototype.setCustomerId = function (customerId) {
                this._persistentData.setId('customerId', customerId);
            };
            /**
             * Visitors user id
             * @cfg {String} userId
             * @accessor
             */
            VisitorProfile.prototype.getUserId = function () {
                return this._persistentData.getId('userId');
            };
            VisitorProfile.prototype.setUserId = function (userId) {
                this._persistentData.setId('userId', userId);
            };
            /**
             * E-Mail address
             * @cfg {String} email
             * @accessor
             */
            VisitorProfile.prototype.getEmail = function () {
                return this._persistentData.getId('email');
            };
            VisitorProfile.prototype.setEmail = function (email) {
                this._persistentData.setId('email', email);
            };
            /**
             * Visitors email hash
             * @cfg {String} emailHash
             * @accessor
             */
            VisitorProfile.prototype.getEmailHash = function () {
                return this._persistentData.getId('emailHash');
            };
            VisitorProfile.prototype.setEmailHash = function (emailHash) {
                this._persistentData.setId('emailHash', emailHash);
            };
            /**
             * Returns true if a profile id is available.
             * @returns {boolean}
             */
            VisitorProfile.prototype.hasIds = function () {
                if (this.getVisitorId()) {
                    return true;
                }
                var ids = this._persistentData.getIds();
                if (ids && Object.keys(ids).length > 0) {
                    return true;
                }
                if (this.getSessionId()) {
                    return true;
                }
                return false;
            };
            /**
             * Returns true if a profile id is available.
             * @returns {}
             */
            VisitorProfile.prototype.getIds = function () {
                return this._persistentData.getIds();
            };
            /**
             * Visitors login state
             * @cfg {String} loginState
             * @accessor
             */
            VisitorProfile.prototype.getLoginState = function () {
                return this._persistentData.getLoginState() || VisitorProfile.LOGIN_STATE_UNKNOWN;
            };
            VisitorProfile.prototype.setLoginState = function (state) {
                if (!ArrayUtils.contains([
                    VisitorProfile.LOGIN_STATE_PREVIOUS_SESSION,
                    VisitorProfile.LOGIN_STATE_SIGNED_IN,
                    VisitorProfile.LOGIN_STATE_SIGNED_OUT,
                    VisitorProfile.LOGIN_STATE_UNKNOWN
                ], state)) {
                    econda.debug.error("Invalid login state: " + state);
                }
                this._persistentData.setLoginState(state);
            };
            /**
             * Standard behavior for user login action.
             * @chainable
             */
            VisitorProfile.prototype.login = function (userData) {
                if (userData === void 0) { userData = null; }
                this._persistentData.setLoginState(VisitorProfile.LOGIN_STATE_SIGNED_IN);
                userData = userData || {};
                if (typeof userData.ids === 'object' && userData.ids !== null) {
                    this._persistentData.setIds({
                        // visitorId: always the cookie value
                        // recipientId: only valid for a single session, so should be ok
                        customerId: userData.ids.customerId || null,
                        userId: userData.ids.userId || null,
                        email: userData.ids.email || null,
                        emailHash: userData.ids.emailHash || null
                    });
                }
                this._persistentData.clearProperties();
                if (typeof userData.properties === 'object' && userData.properties !== null) {
                    this.setProperties(userData.properties);
                }
                return this;
            };
            /**
             * Standard behavior for user logout action. Well clear the user data and
             * set loginState to SIGNED_OUT.
             * @chainable
             */
            VisitorProfile.prototype.logout = function () {
                this._persistentData.setLoginState(VisitorProfile.LOGIN_STATE_SIGNED_OUT);
                this.clearAll();
                return this;
            };
            /**
             * Removes all data from visitor profile
             * @chainable
             */
            VisitorProfile.prototype.clearAll = function () {
                this._persistentData.clearIds();
                this._persistentData.clearProperties();
                return this;
            };
            /**
             * Visitor properties like gender or date of birth,...
             * @cfg {Object} properties
             * @accessor
             */
            VisitorProfile.prototype.getProperties = function () {
                return this._persistentData.getProperties();
            };
            VisitorProfile.prototype.setProperties = function (data) {
                this._persistentData.setProperties(data);
            };
            /**
             * Set single visitor property value
             * @method
             */
            VisitorProfile.prototype.setProperty = function (name, value) {
                this._persistentData.setProperty(name, value);
            };
            /**
             * Get single visitor property value
             * @method
             */
            VisitorProfile.prototype.getProperty = function (name) {
                return this._persistentData.getProperty(name);
            };
            /**
             * Set single visitor custom property value
             * @method
             */
            VisitorProfile.prototype.setCustomProperty = function (name, value) {
                this.setProperty(VisitorProfile.CUSTOM_PROFILE_PROPERTIES_PREFIX + name, value);
            };
            /**
             * Get single visitor custom property value
             * @method
             */
            VisitorProfile.prototype.getCustomProperty = function (name) {
                return this.getProperty(VisitorProfile.CUSTOM_PROFILE_PROPERTIES_PREFIX + name);
            };
            /**
             * @deprecated
             */
            VisitorProfile.prototype.getVisitorHistory = function () {
                return this.getHistory();
            };
            /**
             * Get event history object of visitor
             * @return {econda.recengine.history.VisitorHistory}
             */
            VisitorProfile.prototype.getHistory = function () {
                return this._persistentData.getHistory();
            };
            /**
             * Cleanup data from previous sessions
             * @private
             * @chainable
             */
            VisitorProfile.prototype._onFirstInitOfSession = function () {
                this.setRecipientId(null);
                if (this.getLoginState() === VisitorProfile.LOGIN_STATE_SIGNED_IN) {
                    this.setLoginState(VisitorProfile.LOGIN_STATE_PREVIOUS_SESSION);
                }
                return this;
            };
            /**
             * Read recipientId from uri and save as visitor id
             * @private
             */
            VisitorProfile.prototype._initRecipientId = function () {
                // check for available data
                var uri = new econda.net.Uri(window.location.href);
                var recipientId = uri.getParam('ecmUid');
                if (recipientId) {
                    this.setRecipientId(recipientId);
                }
                return this;
            };
            /**
             * Load data from local storage
             * @private
             */
            VisitorProfile.prototype._initPersistentData = function () {
                this._persistentData = new VisitorData();
                this._persistentData.loadFromBrowser();
                if ((this.getHistory() instanceof VisitorHistory) === false) {
                    this._persistentData.setHistory(new VisitorHistory());
                }
                return this;
            };
            /**
             * @property {String} CUSTOM_PROFILE_PROPERTIES_PREFIX
             * @static
             */
            VisitorProfile.CUSTOM_PROFILE_PROPERTIES_PREFIX = 'cu:';
            /**
             * @property {String} LOGIN_STATE_SIGNED_IN
             * @static
             */
            VisitorProfile.LOGIN_STATE_SIGNED_IN = 'signed_in';
            /**
             * @property {String} LOGIN_STATE_PREVIOUS_SESSION
             * @static
             */
            VisitorProfile.LOGIN_STATE_PREVIOUS_SESSION = 'previous_session';
            /**
             * @property {String} LOGIN_STATE_SIGNED_OUT
             * @static
             */
            VisitorProfile.LOGIN_STATE_SIGNED_OUT = 'signed_out';
            /**
             * @property {String} LOGIN_STATE_UNKNOWN
             * @static
             */
            VisitorProfile.LOGIN_STATE_UNKNOWN = 'unknown';
            return VisitorProfile;
        }(econda.base.BaseClass));
        recengine.VisitorProfile = VisitorProfile;
    })(recengine = econda.recengine || (econda.recengine = {}));
})(econda || (econda = {}));