// access to confomat from context
function Confomat() {
    this.fns = new Array();
    this.fns['producttypeChange'] = new Array();
    this.fns['applicationLoaded'] = new Array();
    this.fns['designChanged'] = new Array();
    this.fns['userLoggedIn'] = new Array();
}
Confomat.prototype = {
    subscribe : function(event, fn) {
        this.fns[event].push(fn);
    },
    unsubscribe : function(event, fn) {
        this.fns[event] = this.fns[event].filter(
            function(el) {
                if ( el !== fn ) {
                    return el;
                }
            }
        );
    },
    fire : function(event, o, thisObj) {
        var scope = thisObj || window;
        /*
        //using while because
        //this does not work in IE 8:
        this.fns[event].forEach(
            function(el) {
                el.call(scope, o);
            }
        );
        */
        var i = 0;
        while(true){
            if(typeof this.fns[event][i] == 'function'){
                this.fns[event][i].call(scope, o);
                i++;
            }else{
                break;
            }
        }
    },
    call : function(callback, arg){
        var globalCallback = 'document.Confomat.'+callback;
        if(typeof eval(globalCallback) == 'function'){
            return eval(globalCallback+'('+arg+')');
        }
    },
    loadProduct: function(productId){
        this.call('setProductId',productId);
    },
    loadBasketItem: function(basketItemId,basketItemUrl){
        this.call('setBasketItemId',basketItemId);
    }
};

// access to context from confomat
function ConfomatContext(){
    this.checkoutUrl = undefined;
    this.shippingDetailsUrl = undefined;
    this.taxDetailsUrl = undefined;
    this.productUrlTemplate = undefined;
    this.popupRef = undefined;
    this.popupLoadingIndicatorUrl = undefined;
}
ConfomatContext.prototype = {
    // configuration
    setCheckoutUrl: function(checkoutUrl){
        this.checkoutUrl = checkoutUrl;
    },
    setShippingDetailsUrl: function(shippingDetailsUrl){
        this.shippingDetailsUrl = shippingDetailsUrl;
    },
    setTaxDetailsUrl: function(taxDetailsUrl){
        this.taxDetailsUrl = taxDetailsUrl;
    },
    setProductUrlTemplate: function(productUrlTemplate){
        this.productUrlTemplate = productUrlTemplate;
    },
    setPopupLoadingIndicatorUrl: function(popupLoadingIndicatorUrl){
        this.popupLoadingIndicatorUrl = popupLoadingIndicatorUrl;
    },

    // actions
    onBasketItemCreated: function (id, shop, productId, appearanceId, sizeId, quantity) {
    },

    onBasketItemUpdated:function(id, shop, oldProductId, productId, appearanceId, sizeId, quantity)  {
    },

    checkout: function(){
        if(this.checkoutUrl != undefined){
            window.location = this.checkoutUrl;
        }
    },

    displayShippingDetails: function(){
        this._openPopupUrl(this.shippingDetailsUrl);
    },

    displayTaxDetails: function(){
        this._openPopupUrl(this.taxDetailsUrl);
    },

    openPopup: function(url, title, width, height){
        if(width === undefined){
            width = 640;
        };
        if(height === undefined){
            height = 320;
        };
        if(url == '' && this.popupLoadingIndicatorUrl){
            url = this.popupLoadingIndicatorUrl;
        }
        this.popupRef = window.open(url, title,'height='+height+',width='+width+'toolbar=no,scrollbar=no');
        if(!this.popupRef){
            return this._false();
        }
        if(window.focus){
            this.popupRef.focus();
        }
        return this._true();
    },

    updatePopup: function(url){
        if(this.popupRef){
            this.popupRef.location = url;
        }else{
            return this.openPopup(url, '');
        }
        return this._true();
    },

    closePopup: function(){
        if(this.popupRef){
            this.popupRef.close();
        }
    },

    getProductUrl: function(productId, viewId){
        if(! this.productUrlTemplate){
            return this._false();
        }
        var url = this.productUrlTemplate.replace(/\[productId\]/, productId).replace(/\[viewId\]/, viewId);
        return url;
    },

    isUserAuthenticated: function(){
        var rtn;
        if(typeof isUserAuthenticated == 'undefined'){
            rtn = 'maybe';
        }else{
            rtn = this._boolReturnValue(isUserAuthenticated);
        }
        return rtn;
    },

    setToken: function(token){
        return createCookie('tok', token, null, 365);
    },

    getToken: function(){
        var tokenValue = getCookieValue('tok');
        if("" != tokenValue){
            // renew token lifetime
            createCookie('tok', tokenValue, null, 365);
        }
        return tokenValue;
    },

    deleteToken: function(){
        return eraseCookie('tok');
    },

    // private
    _openPopupUrl: function(url){
        if(url != undefined){
            Popup.openup({href: url});
        }
    },

    _false: function(){
        return this._boolReturnValue(false);
    },

    _true: function(){
        return this._boolReturnValue(true);
    },

    _boolReturnValue: function(boolean){
        return boolean ? 'true' : 'false';
    }
}

var confomat = new Confomat();
var confomatContext = new ConfomatContext();

// plain function synonyms for actual method calls
function onProductTypeChange(id){
    confomat.fire('producttypeChange', id);
}

function onApplicationLoaded(time){
    confomat.fire('applicationLoaded', time);
}

function onDesignChanged(id){
    confomat.fire('designChanged', id);
}

function onUserLoggedIn(){
    confomat.fire('userLoggedIn');
}

function addToBasket(shopId, productId, appearanceId, sizeId, quantity, onComplete){
    confomatContext.addToBasket(shopId, productId, appearanceId, sizeId, quantity, onComplete);
}

function updateBasketItem (itemId, shopId, oldProductId, newProductId, appearanceId, sizeId, quantity, onComplete) {
    confomatContext.updateBasketItem(itemId, shopId, oldProductId, newProductId, appearanceId, sizeId, quantity, onComplete);
}

function onBasketItemCreated (id, shop, productId, appearanceId, sizeId, quantity) {
    confomatContext.onBasketItemCreated(id, shop, productId, appearanceId, sizeId, quantity);
}

function onBasketItemUpdated (id, shop, oldProductId, productId, appearanceId, sizeId, quantity) {
    confomatContext.onBasketItemUpdated(id, shop, oldProductId, productId, appearanceId, sizeId, quantity);
}

