/*global $, $F, storefront, window, document */

storefront.utils.modalWindow = (function () {
	"use strict";
	
    var priv, api, TERNARY;
 
    /* ================================================================
        modalWindow :: priv
    ================================================================ */ 
    
    priv = {
        parent      : "body",
        window      : null,
        content     : null,
        overlay     : null,
        closeButton : null,
        ownFN       : false,
        noClose     : false,
        source      : "",        
        modus       : 0,
        windowId    : "modalWindow",
		noESC		: storefront.globals.modalWindowESC || true,
        outClick    : storefront.globals.modalWindowOutClick || false,
        noFade      : storefront.globals.modalWindowNoFade || false,
            
        removeElements : function () {  
            $("html").css("overflow", "auto");
            priv.window.remove();  
            priv.overlay.remove();
			//$(document).unbind("resize.$F.modal scroll.$F.modal");
            
            return true;
        },
        
        generateElements : function (width, height) {
            priv.overlay = $("<div>").attr("class", "modalOverlay").css({
                "display"       : "none"
            }); 
            
            priv.closeButton = $("<div>").attr("class", "modalCloseWindow");            

            priv.closeButton.bind("click", priv.removeElements); 
            
            priv.content = $("<div>").attr("class", "modalContent").css({                
                "width"         : width + "px",
                "height"        : height + "px",
                "overflow"      : (priv.modus === "1" ||  priv.modus === "3") ? "hidden" : "auto"
            });
             
            priv.window = $("<div>").attr("id", priv.windowId).attr("class", "modalFrame").css({
                "width"         : width + "px",
                "height"        : height + "px",
                "top"           : $(document).scrollTop() + ($(window).height() / 10) + "px",
                "margin-left"   : (width / -2) + "px",  
                "display"       : "none"
            });
            
            return true;
        },
        
        appendElements : function () {
            priv.content.append(priv.source);  

            TERNARY = (!priv.noClose) ? priv.window.append(priv.closeButton) : "";  
            
            priv.window.append(priv.content);   

            $(priv.parent).append(priv.overlay);
            $(priv.parent).append(priv.window);   
            
            return true;
        },
        
        showElements : function () {
            if (priv.noFade) {
                priv.overlay.show();
                priv.window.show();
            } else {
                priv.overlay.fadeIn(250).fadeTo(250, 0.70);
					
				priv.window.show();
            }
        },
        
        registerESC : function () {
            $(document).keydown(function (e) {
                if (e.which === 27) {  // ESC
                    priv.removeElements();
                }
            }); 
        },
        
        /*scrollBehavior : function ( height ) {
            var viewPortHeight = $(window).height() - 50;
            
            (viewPortHeight < height)
            ?
                $(".modalFrame").css("position", "absolute")
            :
                $("html").css("overflow", "hidden")
            ;            
        },
		*/
		
		
		
		/** not used yet */
		center: function () {
			var view = $F.utils.helper.inView(priv.window);
			//console.log(priv.getTopVal() + " - " + priv.getLeftVal())
			if (!view.left || !view.right) {				
				//return;
			}
			
			priv.window
				.stop()
				.animate({
					//'top' : priv.getTopVal(),
					//'left' : priv.getLeftVal()
				}, 800);
		},	

		/** not used yet */
		getTopVal: function (height) {
			var topVal = "+=0",
				topDistance = parseInt(priv.window.css("padding-top"), 10);
				
			height = height || parseInt($(window).height(), 10);
				
			topVal = (height - parseInt(priv.window.css("height"), 10)) / 2; // get distance
			
			// check if topVal substracts to much, if its the case so set the distance to 
			// max possible. (padding-top:0 is the last value that is in view)
			
			topVal = topVal < 0 && (topDistance - (topVal * -1)) < 0 ? (topDistance * -1) : topVal; 
					
			topVal = topVal > 0 ? "+=" + topVal.toString() : topVal.toString().replace("-", "-=");    
					
			return topVal;
		},
		/** not used yet */
		getLeftVal: function (width) {
			var leftVal = "+=0";
			
			width = width || parseInt($(window).width(), 10);
			
			leftVal = (width - parseInt(priv.window.css("width"), 10)) / 2; // get distance
			
			
			leftVal = leftVal > 0 ? "+=" + leftVal.toString() : leftVal.toString().replace("-", "-=");
			
			return leftVal;
		},
		
		

        buildWindow : function (width, height) {             
            priv.generateElements(width, height);
            priv.appendElements();
            // priv.scrollBehavior( height );
            priv.showElements();   
            
            TERNARY = (!priv.noClose && !priv.noESC) ? priv.registerESC() : "";
            
            return true;
        },
        
        resize: function (width, height, duration, scaleFromCenter) {    
            var topVal = "+=0", // default value for animation (move +/- px) 
				leftVal = "+=0", // default value for animation (move +/- px) 
				topDistance = parseInt(priv.window.css("padding-top"), 10),
				widthChanged = (parseInt(priv.window.css("width"), 10) - width) !== 0,
				heightChanged = (parseInt(priv.window.css("height"), 10) - height) !== 0; 
				
			duration = duration || 0;
            
			if (!widthChanged && !heightChanged) {
				return false; // dont do anything if nothing changed 
			}
				
			if (scaleFromCenter) {
				// build topVal string
				if (heightChanged) { // if height changed
					topVal = (parseInt(priv.window.css("height"), 10) - height) / 2; // get distance
					
					// check if topVal substracts to much, if its the case so set the distance to 
					// max possible. (padding-top:0 is the last value that is in view)
					
					topVal = topVal < 0 && (topDistance - (topVal * -1)) < 0 ? (topDistance * -1) : topVal; 
									
					topVal = topVal > 0 ? "+=" + topVal.toString() : topVal.toString().replace("-", "-=");            
				}   
			}
			
			// build leftVal string
            if (widthChanged) { // if width changed
                leftVal = (parseInt(priv.window.css("width"), 10) - width) / 2; // get distance
				
                leftVal = leftVal > 0 ? "+=" + leftVal.toString() : leftVal.toString().replace("-", "-=");
            }
            
            // resize all affected elements
            priv.window.animate({
                width: width,
                height: height,
                top: topVal, // move to y
                left: leftVal  // move to x
            }, duration, function () {	
				$(this).css({ // translate new pos, so it move on resize
					left: "50%",
					"margin-left": (width / -2) + "px"
				});
			});            
        
            priv.content.animate({
                width: width,
                height: height
            }, duration);
            
            $("#modalWindowFrame").animate({
                width   : width,
                height  : height              
            }, duration);
        },
		
		shake: function (opts) {
			priv.window.css({ left: "" }); // reset css left value			
		
			// shake to the left, shake to the right
			// possible use case is to announce error
			var options = $.extend({}, { times: 4, duration: 150, movepx: 5, test: false }, opts), // defaults and merge
				leftVal = priv.window.css('left'),
				parsedVal = parseInt(leftVal, 10),
				pos = /%$/.exec(leftVal) ? parsedVal / 100 * $("body").width() - priv.window.width() / 2 : parsedVal, // initial position % or px to px
				i,
				posDynamic = function () {	
					$(this).css({ // translate new pos, so it move on resize
						left: "50%",
						"margin-left": (priv.window.width() / -2) + "px"
					});
				};
			
			for (i = 0; i < options.times; i++) {
				// shake
				priv.window.animate(
					{ left: pos + (options.movepx * (i % 2 === 0 ? 1 : -1)) }, // reverse direction toggle
					options.duration,
					posDynamic
				);
			}
						
			// go back to inital pos
			priv.window.animate(
				{ left: pos },
				options.duration,
				posDynamic
			);
		}
    };    
    
    /* ================================================================
        modalWindow :: api
    ================================================================ */ 
    
    api = {    
        init : function (source, width, height, modus, id, noClose) {
            priv.modus = modus;                
            priv.noClose = ($("#debug").length > 0) ? false : noClose; // debug for test
        
            switch (modus) {
			case "1": 
				priv.source = "<iframe width='" + width + "' height='" + height + "' frameborder='0' name='modalWindowFrame' id='modalWindowFrame' scrolling='auto' allowtransparency='true' src='" + source + "'></iframe>";
				break;
				
			case "2": 
				priv.source = $("#pLayer").html();
				break;
				
			case "3":
				priv.source = "<iframe width='" + width + "' height='" + height + "' frameborder='0' name='modalWindowFrame' id='modalWindowFrame' scrolling='auto' allowtransparency='true' src='" + source + "'></iframe>";
				priv.ownFN = true;  
				break;
				
			case "4":
				priv.source = $('#' + id).contents().find('#pLayer').html();
				break;
				
				
			default:
				window.alert("LayerSource is not in case");
				break;
            }
			
			//console.log($(window))
			//$(window).bind("resize.$F.modal", priv.center);
			
			/*
				if smaller then avail space dont scroll center
				 scroll.$F.modal
			*/
                        
            priv.buildWindow(width, height);  

            if (priv.outClick && !priv.noClose) {
                priv.overlay.click(function () {
                    priv.removeElements();
                });  
            }

            return true;
        },
        
        close : function () {
            return priv.removeElements();
        },
        
        removeCloseHandler : function () {
            priv.closeButton.unbind("click", priv.removeElements);
        },
        
        resize : function (width, height, animate, scaleFromCenter) {
            animate = animate || 0;
            
            if (!width || !height) {
				throw "modalWindow::resize - need width and height";
			}
            
            priv.resize(width, height, animate, scaleFromCenter);
        },
		
		shake: function (options) {
			priv.shake(options);
		}
    };  

    /* ================================================================
        JSUNIT :: reference priv to api if activ
    ================================================================ */
    
    if (storefront.globals.JSUNIT === true) {
        api.priv = priv;
    }        
    
    return api;    
}());
