﻿/**
* $.jRecentViewedProducts
* 
* USAGE:
*
* jStorage requires Prototype, MooTools or jQuery! If jQuery is used, then
* jQuery-JSON (http://code.google.com/p/jquery-json/) is also needed.
* (jQuery-JSON needs to be loaded BEFORE jStorage!)
*
**/

(function($) {
    //    if (!$ || !($.toJSON || Object.toJSON || window.JSON)) {
    //        throw new Error("jQuery, MooTools or Prototype needs to be loaded before jStorage!");
    //    }

    var 
    /* The list of viewed products (newest at the end) */
        _recentProducts = new Array(),

    /* Maximum number of products to be stored (default 30) */
        _maxProducts = 30,

    /* function to encode objects to JSON strings */
        json_encode = $.toJSON || Object.toJSON || (window.JSON && (JSON.encode || JSON.stringify)),

    /* function to decode objects from JSON strings */
        json_decode = $.evalJSON || (window.JSON && (JSON.decode || JSON.parse)) || function(str) {
            return String(str).evalJSON();
        },

    /* The prefix used to store settings in jStorage */
        _hema_jStorage_recentViewedProducts_prefix = "hema-recentviewedproducts-";


    ////////////////////////// PRIVATE METHODS ////////////////////////

    function _getStoredString(key, defaultValue) {
        var jStorageKey = _hema_jStorage_recentViewedProducts_prefix + key;
        return $.jStorage.get(jStorageKey, defaultValue)
    }

    function _setStoredString(key, value) {
        var jStorageKey = _hema_jStorage_recentViewedProducts_prefix + key;
        return $.jStorage.set(jStorageKey, value)
    }

    /**
    Load recently-viewed-products from jStorage
    */
    function _init() {
        var products = _getStoredString("products");
        if (products == null) {
            _recentProducts = new Array();
        }
        else {
            _recentProducts = json_decode(products);
        }
        return true;
    }

    /**
    Save the array of recently-viewed-products in jStorage
    */
    function _save() {
        var products = json_encode(_recentProducts);
        _setStoredString("products", products);
    }

    /**
    Get the index of a product-id 
    */
    function _findProductIndex(productId) {
        var resultIndex = -1;

        for (var index = 0; index < _recentProducts.length; index++) {
            if (_recentProducts[index].Product.Id == productId) {
                resultIndex = index;
                break;
            }
        }

        return resultIndex;
    }

    /**
    Generate an array of product-ids in recently-viewed-products
    */
    function _getOldProductIds() {
        var result = new Array();

        var oldestDate = new Date();
        //setDate -1 day to get products older than 24 hours
        oldestDate.setDate(oldestDate.getDate() - 1);

        for (var index = 0; index < _recentProducts.length; index++) {

            var _ProdDate = new Date(_recentProducts[index].Date);

            if (_ProdDate <= oldestDate) {
                result.push(_recentProducts[index].Product.Id);
            }
        }
        return result;
    }

    /**
    Retreive the updated values for the specified product-ids
    */
    function _getProductUpdateUrl(productIds) {
        var url = '/_layouts/ViewServices/RecentViewedProductsService.ashx';
        if (productIds.length > 0) {
            url = url + '?product=' + productIds.join('&product=');
        }
        return url;
    }

    /**
    Replace the specified product in the recently-viewed-products
    */
    function _updateProduct(id, updatedProduct) {
        var index = _findProductIndex(id);
        if (index >= 0) {
            if (updatedProduct == null) {
                // product no longer available in the shop-catalog
                // remove the detail-url and image from the local-storage
                _recentProducts[index].Product.DetailUrl = null;
                //Set product not available image
                _recentProducts[index].Product.ImageUrl = '/_layouts/1043/images/hema/product-niet-beschikbaar.jpg';
            }
            else {
                // update the product in the local storage
                _recentProducts[index].Product = updatedProduct;
            }
            _recentProducts[index].Date = new Date();
        }
    }

    /**
    Replace the specified product in the recently-viewed-products
    */
    function _GetRecentFromStorage(count) {
        var start = _recentProducts.length - count;
        if (start < 0) {
            start = 0;
        }

        return _recentProducts.slice(start).reverse();
    }

    /**
    Get the date of the oldest viewed product
    */
    function _getMaxAge() {
        var oldest = new Date();

        for (var index = 0; index < _recentProducts.length; index++) {
            oldest = Math.min(_recentProducts[index].Product.Date, oldest);
        }

        return oldest;
    }

    /**
    Resize _recentProducts if to many products are added
    */
    function _resize() {
        if (_recentProducts.length > _maxProducts) {
            _recentProducts.splice(0, _recentProducts.length - _maxProducts);
        }
    }

    ////////////////////////// PUBLIC INTERFACE /////////////////////////

    $.jRecentViewedProducts = {

        /**
        Add or update a product in the recently-viewed-products list
        */
        add: function(product) {

            var recentProduct = { Product: product, Date: new Date().toLocaleString() };

            var productIndex = _findProductIndex(product.Id);

            // is the product already in the recent-products? 
            if (productIndex >= 0) {
                //remove the product from the array
                _recentProducts.splice(productIndex, 1);
            }

            _recentProducts.push(recentProduct);

            _resize();

            _save();

        },

        /**
        Update the information of all products stored in the 
        recently-viewed-products longer than 24 hours ago.
        */
        update: function(callback) {
            var productIds = _getOldProductIds();
            if (productIds.length > 0) {
                var url = _getProductUpdateUrl(productIds);
                $.ajax({
                    url: url,
                    dataType: 'jsonp',
                    success: function(data) {
                        if (data.Products) {
                            for (var index = 0; index < data.Products.length; index++) {
                                _updateProduct(productIds[index], data.Products[index]);
                            }
                        }
                        if (typeof (callback) == "function") {
                            callback();
                        }
                    }
                });
            }
            else
            { callback(); }
        },

        /**
        Remove all recently-viewed-products from the storage
        */
        clear: function() {
            // replace all products with an empty array
            _recentProducts = new Array();
            _save();
        },

        /**
        Return the latest [count] products from the stored recently-viewed-products
        */
        getRecent: function(count) {
            var start = _recentProducts.length - count;
            if (start < 0) {
                start = 0;
            }

            return _recentProducts.slice(start).reverse();
        },

        /**
        Change the maximum products stored in recently-viewed-products.
        */
        setMaxProducts: function(max) {
            _maxProducts = max;
            _resize();
        }
    };

    // Initialize jStorage
    _init();

})(window.jQuery || window.$);




