/*
 * Lightbox overlays
 * @author Lee Daffen
 */

if(typeof NAP == "undefined") {
	var NAP = {};
}

NAP.overlayPanel = function(opts) {
	/* opts = { title: title of the dialog [string],
				message: message to alert [string],
				height: optional, height of dialog, e.g. 200 [integer],
				width: optional, defaults to 180px, width of dialog, e.g. 100 [integer],
				top: optional, top position [integer],
				left: optional, left position [integer],
				type: alert / confirm / info, alert has one 'ok' button, confirm has one 'confirm' and one 'cancel' button, info has none [string],
				callback: optional, function to call on confirm click, returns confirm state as argument [function],
				onReady: optional, function to call when the dialog box HTML is available in the DOM [function],
				confirmText: text to display on the confirm button [string],
				cancelText: text to display on the cancel button [string],
				customButtons: custom button html. requires an onReady method passed to the constructor to handle event binding [string]
				closeButton: custom close button HTML. Inserted within #lighbox-close div
				theme: dark/light, sets the overlay background color [string],
				addClass: optional additional classname for the lightbox-container [string],
				modal: optional, defaults to false, modal dialog (requires user interaction within the dialog) [boolean],
				overlayHTML: html for custom overlay,
				keepOpenOnConfirm: optional, defaults to false, defines if the panel auto-closes on user confirmation
			} */

	var confirmAlt = (opts.type == 'alert') ? 'OK' : 'Confirm' ,
        confirmImg = (opts.type == 'alert') ? '/mrporter/build/2011.17.00/images/buttons/ok.gif' : '/mrporter/build/2011.17.00/images/buttons/confirm.gif',
        cancelImg = '/mrporter/build/2011.17.00/images/buttons/cancel.gif',

        confirmText = opts.confirmText || '<input type="image" value="'+confirmAlt+'" class="overlay-alert-button lightbox-ok" id="overlay-confirm-button" src="'+confirmImg+'" />',
		cancelText = opts.cancelText || '<input type="image" value="Cancel" class="overlay-alert-button lightbox-cancel" id="overlay-cancel-button" src="'+cancelImg+'" />',
		height = (opts.height) ? "height:"+opts.height+"px;" : "",
		width = (opts.width) ? "width:"+opts.width+"px;" : "width:180px;",
		overlayMaskColour = (opts.theme.toLowerCase() == "light") ? "#FFF" : "#000" ,
		//correction = (navigator.appName.indexOf('Microsoft') != -1) ? 21 : 0 ,
		pageHeight = $(document).height(),
		pageWidth = (navigator.appName.indexOf('Microsoft')!= -1) ? $('body').attr('clientWidth') : $(document).width(),        
		modal = opts.modal || false,
        customButtons = opts.customButtons || '',
		closeButton = (modal) ? "" : (opts.closeButton) ? '<div id="lightbox-close">'+opts.closeButton+'</div>' : '<div id="lightbox-close"><img src="/mrporter/build/2011.17.00/images/buttons/close-overlay.gif" alt="Close" class="close" /></div>' ,
        mask = (opts.mask) || 'show',
        showMaskCss = (mask == 'show') ? 'display:block':'display:none',
        keepOpenOnConfirm = opts.keepOpenOnConfirm || false,

		// create the overlay mask HTML
		overlayMask = ['<div id="overlay-mask" style="',showMaskCss,'; height:',pageHeight,'px; width:',pageWidth,'px; position:absolute; top:0; left:0; background-color:',overlayMaskColour,'; opacity:0; filter:alpha(opacity=0); z-index:999999;">&nbsp;</div>'].join(""),
        buttons = '';

    // create the overlay buttons HTML
    switch(opts.type) {
        case 'confirm':
            buttons = confirmText + cancelText;
            break;
        case 'alert':
            buttons = confirmText;
            break;
        case 'custom':
            buttons = customButtons;
            break;
        default:
            buttons = '';
    }

    // create the overlay dialog HTML
    var alertBox = (opts.type === 'custom' && opts.boxHTML) ?
        opts.overlayHTML      
    : [
        '<div id="lightbox-container" style="position:absolute;z-index:1000001;',width,height,'">',
        '<div id="lightbox-top">',closeButton,opts.title,'</div>',
        '<div id="lightbox-middle">',opts.message,'</div>',
        '<div id="lightbox-bottom">',
        buttons,
        '</div></div>'
    ].join("");

	function hideAlert() {
		$("#overlay-mask").fadeOut("fast", function() {
			$(this).remove();
		});
		$("#lightbox-container").fadeOut("fast", function() {
			$(this).remove();
		});

		// replace the scrollbars in IE6 (only required for position:fixed dialogs)
		// if(navigator.appVersion.indexOf("MSIE 6.0") != -1) $("html").css("overflow","auto");
	}

	function showAlert() {
		hideAlert();	// remove any existing dialogs from the page

		// remove the scrollbars in IE6 (only required for position:fixed dialogs)
		// if(navigator.appVersion.indexOf("MSIE 6.0") != -1) $("html").css("overflow","hidden");

		var opacity = (opts.theme == "light") ? 0.50 : 0.35 ;
		$(overlayMask)
			.appendTo($("body"))
			.animate({opacity:opacity}, "fast", function() {
				$(alertBox).appendTo($("body"));

				// calculate the left and top values to position the dialog in the centre of the viewport
				var boxPosX = (typeof opts.left != "undefined") ? opts.left : Math.max((($(window).width())/2) - (parseInt($("#lightbox-container").width())/2) + $(document).scrollLeft(),0),
					// 1/2 width of visible bit - 1/2 width of the dialog box + left scroll offset of the visible bit
					boxPosY = (typeof opts.top != "undefined") ? opts.top : Math.max((($(window).height())/2) - (parseInt($("#lightbox-container").height())/2) + $(document).scrollTop(),0);
					// 1/2 height of visible bit - 1/2 height of the dialog box + top scroll offset of the visible bit

				$("#lightbox-container")
					.css({
						"left":boxPosX+"px",
						"top":boxPosY+"px"
					})
					.fadeIn("fast", function() {
						if(opts.onReady) opts.onReady();
					});

				if(typeof opts.addClass != "undefined") {
					$("#lightbox-container").addClass(opts.addClass);
				}

				bindClicks();
			});

		if(!modal) {
			$("#overlay-mask").click(function() {
				if(opts.callback) { opts.callback(); }
				hideAlert();
			});
		}
	}

	function bindClicks() {
		if(opts.type == "confirm") {
			$("#overlay-confirm-button").click(function() {
				if(opts.callback) { opts.callback(true); }
                if(!keepOpenOnConfirm) { hideAlert(); }
			});
			$("#overlay-cancel-button").click(function() {
				if(opts.callback) { opts.callback(false); }
				hideAlert();
			});
		} else {
			$("#overlay-confirm-button").click(function() {
				if(opts.callback) { opts.callback(); }
				hideAlert();
			});
		}
		$("#lightbox-close").click(function() {
			if(opts.callback) { opts.callback(); }
			hideAlert();
		});
	}

	showAlert();
    
    NAP.overlayPanel.hideAlert = hideAlert;
};

// basket dialog
NAP.headerDialog = function(data, callback, notificationType, isMobile) {

    var imgRes = (isMobile) ? 's' : 'xs';
    var statusMsgsSuccess = getStatusMessage(notificationType)[0];
    var statusMsgsFailure = getStatusMessage(notificationType)[1];

    var displayTimeoutSecs = 5;
    var displayTimeout;
    var messageHTML;
    var containerType;
    var itemStatuses = {
        success: [],
        failed: [],
        all: [],
        statusMap: []
    };
    var removeOverlay = function() {
        $('#shop-bag-added').remove();
        clearTimeout(displayTimeout);
    };
    var hideOverlay = function() {
        $('#shop-bag-added').fadeOut(function() {
            removeOverlay();
            if(typeof callback === 'function') callback();
        });
    };
    var showOverlay = function() {
        $(messageHTML).appendTo('#content').fadeIn();
    };
    var updateImage = function(id, sku) {        
        getProductDetailsForSku(sku,
            function (data) {
                var product = data.searchableProductInfo;
                $('#'+id+' .thumb img').attr('src','//www.mrporter.com/images/products/'+product.productId+'/'+product.productId+'_mrp_in_'+imgRes+'.jpg').attr('alt',product.title + ' by ' + product.designer);
            });
    };

    //return [statusMsgsSuccess, statusMsgsFailure] for wish list or shopping bag notification
    function getStatusMessage(notificationType) {
        var statusMsgsSuccess;
        var statusMsgsFailure;
        if (notificationType == 'bag-header-notification') {
            var msgSuccess = 'Added to bag';
            var msgFailure = 'Not added';
            statusMsgsSuccess = {
                ADDED : msgSuccess,
                ADDED_SOME : msgSuccess,
                INCREASE_QUANTITY : msgSuccess
            };
            statusMsgsFailure = {
                ADDED_ALREADY : 'Already added',
                NO_DATA_TO_ADD : msgFailure,
                MAXIMUM_ITEMS_EXCEED : msgFailure,
                NO_PURCHASABLE : msgFailure
            };
        } else if (notificationType == 'wishlist-header-notification') {
            statusMsgsSuccess = {
                ADDED : 'Added To Wish List',
                ALREADY_ADDED : 'Already Added'
            };
            statusMsgsFailure = {
                NOT_ADDED : 'Not Added',
                WISHLIST_DOES_NOT_EXIST : 'Not Added'
            };
        }
        return [statusMsgsSuccess, statusMsgsFailure];
    }

    // returns an object containing lists of product SKUs based on their 'add to basket' status
    function getStatuses() {
        var statusMap = data.mapOfStatuses;
        var productSku, productStatus;
        var mapCount = 0;
        var productStatusArray = [], successfulProductArray = [], failProductArray = [];

        for(productSku in statusMap) {
            mapCount++;
            productStatusArray.push(productSku);

            productStatus = statusMap[productSku];
            if(statusMsgsSuccess[productStatus]) {
                successfulProductArray.push(productSku);
            } else if(statusMsgsFailure[productStatus]) {
                failProductArray.push(productSku);
            }
        }

        return {
            all: productStatusArray,
            statusMap: statusMap,
            success: successfulProductArray,
            failed: failProductArray
        }
    }

    function getProductDetailsForSku(sku, callback, errorHandler) {
        var pid = sku.split("-")[0];
        $.getJSON("/"+NAP.getChannel()+'/api/feed/searchableproduct/'+pid+'/xs.json', callback, errorHandler);
    }

    function buildItemList(type) {
        // iterate over the success map and create an instance for each in the dialog container
        var listToUse = itemStatuses[type];
        var messages = (type === 'success') ? statusMsgsSuccess : statusMsgsFailure ;
        var statusMap = itemStatuses.statusMap;

        function setLinkUrl() {
            switch(containerType) {
                case 'bag-header-notification':
                    return '/'+NAP.getChannel()+'/shoppingbag.mrp';
                case 'wishlist-header-notification':
                    return '/'+NAP.getChannel()+'/wishlist.mrp';
                default:
                    return '#';
            }
        }

        for(var i in listToUse) {
            var sku = listToUse[i];
            var linkUrl = setLinkUrl();
            $(['<div class="shop-bag-',type,'-item sku-',sku,'" id="',type,'-item-',i,'">',
                    '<div class="thumb"><a href="'+linkUrl+'"><img src="/mrporter/build/2011.17.00/images/wardrobe_manager/ajax-loader-xs.gif" alt="loading..." /></a></div>',
                    '<a href="'+linkUrl+'"><span>', messages[statusMap[sku]] ,'</span></a>',
                '</div>'
            ].join('')).appendTo('#shop-bag-added-mid');

            // get the product details for each sku in the status map
            updateImage(type+'-item-'+i, sku);
        }
    }

    this.setContainerHTML = function(html){
         messageHTML = html;
    };

    this.setContainerType = function(type) {
        containerType = type;
    };

    this.show = function(){

        if(data) {
            // test the data object's type
            if(typeof data === 'object' && data.mapOfStatuses) {
                itemStatuses = getStatuses();
            } else if(typeof data === 'string') {
                itemStatuses = {
                    all: [data],
                    statusMap: [],
                    success: [data],
                    failed: []
                };
            }
        }

        // remove any instances of the dialog left in the DOM
        removeOverlay();

        // create and display a new dialog
        showOverlay();

        if(itemStatuses.success.length > 0) {
            buildItemList('success');
        }

        // if both success and failed lists exist add a divider element
        if(itemStatuses.success.length > 0 && itemStatuses.failed.length > 0) {
            $('<div class="shop-bag-divider"></div>').appendTo('#shop-bag-added-mid');
        }

        if(itemStatuses.failed.length > 0) {
            buildItemList('failed');
        }

        $('.close').click(hideOverlay);

        displayTimeout = setTimeout(hideOverlay, displayTimeoutSecs*1000);

        $("#shop-bag-added").hover(
            function () {
                clearTimeout(displayTimeout);
            },
            function () {
                displayTimeout = setTimeout(hideOverlay, displayTimeoutSecs*1000);
            }
        );


    }
};

NAP.notificationDialog = function(data, callback, notificationType, isMobile) {
    var offsetLeft = null;
    var leftPositionCss = '';

    //default the notificationType to bag.
    if (notificationType == undefined || notificationType == null) notificationType = 'bag-header-notification';
    var closeButtonHtml = ( isMobile ) ? ' <div class="close"><div class="close_btn_txt">CLOSE</div> <div class="close_btn_x">X</div></div>' : '<img src="/mrporter/build/2011.17.00/images/buttons/close-overlay.gif" alt="Close" class="close" />';

//    If a Wishlist notification then the left position needs to be adjusted.
//    In the future, when all notification use this, the left position calculation needs to be made more generic
//    Need to workout left offset in 2 part,
//    First add the Parents position and then the childs position.
    if (notificationType === 'wishlist-header-notification'){
        offsetLeft = $('#sign-in-links-wishlist').offsetParent().position().left;
        offsetLeft = offsetLeft + $('#sign-in-links-wishlist').position().left - 70;
        leftPositionCss = 'left: ' + offsetLeft + 'px;';
    }

    var containerHtml = [
        '<div id="shop-bag-added" class="' + notificationType + '" style="display:none;' + leftPositionCss + '">',
            '<div id="shop-bag-added-top"></div>',
            '<div id="shop-bag-added-mid">',
                closeButtonHtml,
            '</div>',
            '<div id="shop-bag-added-btm"></div>',
        '</div>'
    ].join('');

    var headDialog = new NAP.headerDialog(data, callback, notificationType, isMobile);
    headDialog.setContainerHTML(containerHtml);
    headDialog.setContainerType(notificationType);
    headDialog.show();
};

