﻿var commerce = commerce || {};
(function() {
    // ..create the product functionality base prototypes..
    commerce.product = commerce.product || {};
    commerce.product._data = commerce.product._data || {};

    commerce.ui = commerce.ui || {};


    /*
    ** e-commerce product comparison functionality.
    **
    ** Calls .asmx web services to interact with the
    ** current context, basket and comparison lists.
    */
    if (typeof commerce._callws !== 'function') {
        commerce._callws = function(options) {
            var fn_wsok = function(data, status) {
                // ..convert from Microsoft.NET json format,
                // which serializes into a "d" field to
                // prevent cross-site scripting..
                if (typeof data == 'object' && data != null && typeof data.d != 'undefined')
                    data = eval(data.d);
                if (typeof options.success == 'function' && data.status == 200)
                    options.success(data, status);
                else if (typeof options.error == 'function')
                    options.error(data, status);
                return false;
            };
            var fn_wserr = function(data, status) {
                if (typeof data == 'object' && data != null && typeof data.d != 'undefined')
                    data = eval(data.d);
                if (typeof options.error == 'function')
                    options.error(data, status);
                return false;
            };
            var data = $.extend({ success: fn_wsok, error: fn_wserr }, options);
            if (data.success != fn_wsok) data.success = fn_wsok;
            if (data.error != fn_wserr) data.error = fn_wserr;
            $.ajax(data);
        };
    }

    if (typeof commerce.product._fetch !== 'function') {
        commerce.product._fetch = function(id, options) {
            var item = null;
            options = $.extend({ async: true, success: function(data, status) { commerce.product._data['$' + data.id] = (item = data); } }, options);
            commerce._callws($.extend({ url: '/services/products.asmx/Get', type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', data: JSON.stringify({ key: id }) }, options));
            return item;
        };
    }

    if (typeof commerce.product.consider !== 'function') {
        commerce.product.consider = function(id, options) {
            commerce._callws($.extend({ url: '/services/products.asmx/Consider', type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', data: JSON.stringify({ key: id }) }, options));
            return false;
        };
    }

    if (typeof commerce.product.disregard !== 'function') {
        commerce.product.disregard = function(id, options) {
            var k = JSON.stringify((id = id || '') === '' ? {} : { key: id });
            commerce._callws($.extend({ url: id === '' ? '/services/products.asmx/DisregardAll' : '/services/products.asmx/Disregard', type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', data: k }, options));
            return false;
        };
    }

    if (typeof commerce.ui.new_comparison_line !== 'function') {
        commerce.ui.new_comparison_line = function(result) {
            if (typeof result == "undefined")
                return '';

            var li = $(document.createElement('li')).addClass('product').css('display', 'none');
            var a_name = $(document.createElement('a')).html('<span class="title">' + result.name + '</span>').attr({ href: result.url, title: result.name });
            var thumbn = $(document.createElement('img')).attr({ src: '/assets/en/catalogue/xxsmall/' + result.id + '.jpg', title: result.name }).css('vertical-align', 'middle');

            var a_butn = $(document.createElement('a')).html('<img src="/assets/en/site/buttons/comparison-remove.png" />').addClass('remove').attr({ href: '#?disregard=' + result.id }).css({ cursor: 'pointer' }).click(function() {
                commerce.product.disregard(result.id, { success: function() { li.slideUp('fast'); } });
            });
            li.append(a_name).append(a_butn);
            a_name.prepend(thumbn);
            li.fadeIn('slow');
            return li;
        };
    }

    if (typeof commerce.ui.new_comparison_list !== 'function') {
        commerce.ui.new_comparison_list = function(results, status) {
            $('#product-comparison .product-list').empty();
            switch (results.status) {
                case 200: // OK
                    if (results.data.length === 0) {
                        var span = $(document.createElement('span')).addClass('message');
                        $('#product-comparison .product-list').append(span);
                        span.text('You currently have no products for comparison');
                        return;
                    }

                    for (var index = 0; index < results.data.length; index++) {
                        var element = commerce.ui.new_comparison_line(results.data[index]);
                        $('#product-comparison ul.product-list').append(element);
                    }
                    break;

                case 404: // Product not found
                    var span = $(document.createElement('span')).addClass('message');
                    $('#product-comparison .product-list').append(span);
                    span.text('The product you requested could not be found!');
                    break;

                case 409: // Product definition not apporopriate
                    var span = $(document.createElement('span')).addClass('message');
                    $('#product-comparison .product-list').append(span);
                    span.text('The product you requested is not of type "' + results.message + '"; only products of the same type can be compared.');
                    break;

                default: // General error
                    var span = $(document.createElement('span')).addClass('message');
                    $('#product-comparison .product-list').append(span);
                    span.text("We don't seem to be able to to add the product for comparison; sorry about that.");
                    break;
            }
        };
    }


    /*
    ** e-commerce product variant styles functionality.
    **
    ** Calls .asmx web services to interact with the
    ** current context, basket and comparison lists.
    */
    if (typeof commerce.product.find !== 'function') {
        commerce.product.find = function(id, attrs) {
            var item = commerce.product._data['$' + id] || commerce.product._fetch(id);
            if (item == null) return null;
            if (arguments.length == 1)
                return item;
            if (attrs == null || attrs.length === 0)
                return null;
            for (var v = 0, m = 0; v < item.variants.length; v++, m = 0) {
                for (var n = 0; n < attrs.length; n++) {
                    if (typeof item.variants[v][attrs[n].key] === 'undefined')
                        continue;
                    var a = (attrs[n].value || '').toLowerCase();
                    var b = (item.variants[v][attrs[n].key].id || '').toLowerCase();
                    if (a == b) m++;
                }
                if (m === attrs.length) return item.variants[v];
            }
            return null;
        };
    }

    if (typeof commerce.product.place !== 'function') {
        commerce.product.place = function(p, v, c, options, bcnt) {
            var fn = function(data, status) {
                var msg = 'Unable to add product to basket; system failure.';
                if (status == 'success') {
                    var json = eval('(' + data + ')');

                    if (json !== null && typeof json.message != 'undefined') {
                        $('a#basket-nav-summary').html('<span>Basket:</span> ' + json.message);
                    }
                   
                    if (typeof json.products != 'undefined' && json.products.length != 0) {
                        msg = (json.products[0].addToBasket ? 'This product has been added to your basket' : (json.products[0].reason || 'unknown error'));
                        setTimeout("$('#basket-message').fadeOut('normal');", 5000);
                    } else if (typeof json.message != 'undefined') {
                        msg = json.message;
                    }
                    Omniture.SubmitAddToBasketSingle(p, v, c, options.quantity, bcnt);
                }
                $('#basket-message .message').html(msg);
                $('#basket-message').fadeIn('fast');
                return false;
            };
            if (p !== null && typeof p != 'string') p = p.id; // ..extract the product id..
            if (v !== null && typeof v != 'string' && typeof v != 'undefined') v = v.id; // ..extract the variant id..
            //If the variant is undefined, it implies that the variant doesnt exist for the choosen product, therefore
            //set it to null
            if (typeof v == 'undefined') v = '';
            var o = $.extend({ command: 'AddToBasket', ajax: true, pid: p, vid: v }, options);
            var h = $.ajax({url: '/handler.aspx', data: o, success: fn, error: fn, dataType: 'text', cache: false });

        };
    }


    /*
    ** e-commerce product variant styles functionality.
    **
    ** Calls .asmx web services to interact with the
    ** current context, basket and comparison lists.
    */
    if (typeof commerce.product.find !== 'function') {
        commerce.product.find = function(id, attrs) {
            var item = commerce.product._data['$' + id] || commerce.product._fetch(id);
            if (item == null) return null;
            if (arguments.length === 1)
                return item;
            if (attrs == null || attrs.length === 0)
                return null;
            for (var v = 0, m = 0; v < item.variants.length; v++, m = 0) {
                for (var n = 0; n < attrs.length; n++) {
                    if (typeof item.variants[v][attrs[n].key] === 'undefined')
                        continue;
                    var a = (attrs[n].value || '').toLowerCase();
                    var b = (item.variants[v][attrs[n].key].id || '').toLowerCase();
                    if (a === b) m++;
                }
                if (m == attrs.length) return item.variants[v];
            }
            return null;
        };
    }


    /*
    ** e-commerce product user interface functionality.
    **
    ** Utility functions for making swatches from drop-down lists
    ** and intercepting the product variant controls range selector.
    */
    if (typeof commerce.ui.swatchify !== 'function') {
        commerce.ui.swatchify_resolve = function(container) {
            var options = [];
            container.find("select.property").each(function(index, select) {
                var id = select.id.match(/[a-zA-Z0-9]+$/) || [];
                if (id.length === 0) return;

                options.push({ key: id[0].toLowerCase(), value: $(select).val() || '' });
            });

            var id = container.find("input[type='hidden'].product-key").val();
            //return the product id if the choosen options is null
            //If the choosen option is null, it implies that the selected item is a Product without any variant
            if (commerce.product.find(id, options) == null) {
                return id;
            }
            else {
                return commerce.product.find(id, options);
            }
        };

        commerce.ui.swatchify_range = function(container, options) {
            if (container === null) return;
            var lists = container.find('select.colour');

            commerce.ui.swatchify(lists, options);
            lists.change(function(eventObject) {
                var id = container.find("input[type='hidden'].product-key").val();
                var pr = commerce.product.find(id);
                if (pr === null) return true;

                // ..find the 'size' selector and restructure the values
                // based on the keys found in the variant collection of
                // the product..
                var selector = container.find('select.property.size');
                if (selector !== null && selector.size() !== 0) {
                    var prev = selector.val();
                    selector.empty();

                    for (var index = 0; index < pr.variants.length; index++) {
                        var variant = pr.variants[index];
                        if (typeof variant.colour !== 'undefined' && typeof variant.size !== 'undefined' && variant.colour.id === $(this).val())
                            selector.append('<option value="' + variant.size.id + '">' + variant.size.descr + '</option>');
                    }

                    // ..reset the previously selected value (if present)
                    // and issue any custom change event handler specified
                    // in the options given..
                    selector.val(prev);
                }
                if (typeof options.change === 'function') {
                    eventObject = $.extend(eventObject, { data: commerce.ui.swatchify_resolve(container) });
                    options.change(eventObject);
                }
            });

            // ..map all other drop downs tagged as being variant properties
            // with the custom callback handler; resolve the selected product
            // and pass through as a secondary parameter..
            container.find("select.property").filter(":not(.colour)").change(function(eventObject) {
                if (typeof options.change === 'function') {
                    eventObject = $.extend(eventObject, { data: commerce.ui.swatchify_resolve(container) });
                    options.change(eventObject);
                }
            });
        };

        commerce.ui.swatchify = function(lists, options) {
            if (lists === null || lists.size() == 0)
                return;
            options = $.extend({}, options);
            lists.each(function(index, select) {
                var choice = $(select).children(':selected').val();
                var div = $(document.createElement('div')).addClass('swatches').width($(select).width());
                $(select).css('display', 'none').children('option').each(function(index, option) {
                    var a = $(document.createElement('a'));
                    var i = $(document.createElement('img'));
                    a.attr({ alt: option.text, href: '#' }).addClass('swatch').append(i).addClass($(option).val() == choice ? 'selected' : '').click(function() {
                        $(this).parent().children('a.swatch').removeClass('selected');
                        $(this).addClass('selected');
                        $(select).val(option.value).change();
                        return false;
                    });
                    i.attr('src', '/assets/en/catalogue/swatches/' + $(option).val().replace(/[^\w]/, '') + '.jpg');
                    div.append(a);
                });

                $(select).before(div);
            });
        };
    }

    if (typeof commerce.ui.intercept !== 'function') {
        commerce.ui.intercept = function(buttons) {
            if (buttons === null || buttons.size() == 0)
                return;

            buttons.each(function(index, button) {
                $(button).click(function() {
                    var options = {};
                    var item = commerce.ui.swatchify_resolve($(button).parent());
                    if (item == null) { return true; } // ..submit the form; we can't find the product!..

                    $(button).parent().find(".product-options select.non-property").each(function(index, select) {
                        var id = select.id.match(/[a-zA-Z0-9]+$/) || [];
                        if (id.length === 0) return;

                        options[id[0].toLowerCase()] = $(select).val() || '';
                    });
                    // ..the quantity is a special case; select it directly..
                    var id = $(button).parent().find("input[type='hidden'].product-key").val();
                    var quantity = $('select.non-property.quantity');
                    options.quantity = quantity.size() == 0 ? '1' : quantity.val();
                    var bcnt = $('#basket-count').val();
                    if (bcnt == "True")
                    { $('#basket-count').val('False'); }
                    var cid = $('#product-cat').val();
                    commerce.product.place(id, item.id, cid, options, bcnt);
                    return false;
                });
            });
        };
    }
} ());
