(function($) {
    function Layer() {
        var overlayElement;
        var layerElement;
        var content;
        var scroll;
        var scrollInterval;
        var self = this;
		var options = {
			fixedClose: true,
			layerTemplate: '<div id="layer">' + 
								'<div class="layerContainer">' + 
									'<div class="layer">' + 
										'<div class="layerBorder"><div class="layerInner"><div class="layerContent"></div></div></div>' + 
										'<div class="layerTopLeft"></div>' + 
										'<div class="layerTopRight"></div>' + 
										'<div class="layerBottomLeft"></div>' + 
										'<div class="layerBottomRight"></div>' + 
										'<div class="layerTop"></div>' + 
										'<div class="layerBottom"></div>' + 
										'<a class="layerClose" href="#">###close###</a>' + 
									'</div>' + 
								'</div>' + 
								'<a class="layerClose" href="#">###close###</a>' + 
							'</div>'
		};

		this.setOptions = function(config) {
			$.extend(options, config);
		}

        this.open = function(url, callback, iframe, fullscreen, execJavaScript, formPost) {
            $(window).resize();
            if(!overlayElement || !layerElement) {
                init();
                $(window).resize();
            }
            else {
                resetScrolling();
            }

            if(fullscreen) {
                layerElement.addClass('fullscreen');
            }
            else {
                layerElement.removeClass('fullscreen');
            }
            layerElement.removeClass('fixedClose');

			if (url[0] != '#') {
				if(iframe) {
					content.html('<iframe border="0" frameborder="0" width="100%" height="500" src="' + url + '"></iframe>');
					if (!!('ontouchstart' in window)) {
						updateScrolling();
					}
				}
				else {
					layerElement.addClass('loading');
					content.empty();

					if (formPost) {
						$.post(url, formPost, function(data) {
							updateLayer(data, execJavaScript, callback);
						});	
					}
					else {
						$.get(url, function(data) {
							updateLayer(data, execJavaScript, callback);
						});
					}
				}
			}
			else if ($(url).length > 0) {
				content.html($(url).html());

				if (callback) {
					callback(content);
				}

				if (!!('ontouchstart' in window)) {
					updateScrolling();
				}
			}

            $('body').css('overflow', 'hidden');
            if($.browser.msie && $.browser.version < 9){
                overlayElement.show();
                layerElement.show();
            }
            else {
                overlayElement.fadeIn(900);
                layerElement.fadeIn(900);
            }
        }
        
		var updateLayer = function(data, execJavaScript, callback) {
			layerElement.removeClass('loading');

			var result = '';
			if (execJavaScript) {
				result = data.replace(/[\r\n]+/g, '').replace(/^.*<div id="content"[^>]*>(.*)<div id="context">.*$/gim, '$1');
				content.html(result);
			}
			else {
				result = $('<div>' + data + '</div>');
				content.html(result.find('#content').html());
			}

			var height = content.height();
			content.css('height', '100px');

			if (callback) {
				callback(content);
			}

			content.animate({ height: height + 'px', duration: 1100});

			setTimeout(function(){
				content.css('height', '');

				if (!!('ontouchstart' in window)) {
					updateScrolling();
				}
			},1100);
		}

        this.close = function() {
            if(scrollInterval){
                clearInterval(scrollInterval);
            }
            
            if($.browser.msie && $.browser.version < 9){
                overlayElement.hide();
                layerElement.hide();
            }
            else {
                overlayElement.fadeOut(900);
                layerElement.fadeOut(900);
            }

            setTimeout(function(){
                $('body').css('overflow', '');
                overlayElement.hide();
                layerElement.hide();
                content.empty();
            }, 900);
        }
        
        this.update = function() {
            updateScrolling();
        }
    
        var init = function() {

			var close = 'close';
			if ($('#close').length > 0) {
				close = $('#close').text();
			}

            if(!layerElement) {
				var layerTpl = options.layerTemplate;
				layerTpl = layerTpl.replace('###close###', close);
                $('body').append('<div id="overlay"></div>' + layerTpl);

                overlayElement = $('#overlay');
                layerElement = $('#layer');
                content = $('#layer').find('div.layerContent');

                layerElement.find('a.layerClose,a.layerQuit').click(function(e){
                    e.preventDefault();
                    self.close();
                    return false;
                });
                $(document).unbind('keyup').keyup(function(e) {
                  if(e.keyCode == 27) {   // esc
                      self.close();
                  }
                });

				if (options.fixedClose) {
					layerElement.find('div.layerContainer').bind('scroll', function(){
						if($(this).scrollTop() > 75){
							layerElement.addClass('fixedClose');
						}
						else {
							layerElement.removeClass('fixedClose');
						}
					});
				}

                if (!!('ontouchstart' in window)) {
                    initScrolling();
                }
            }
        }
    
        var initScrolling = function() {
            scroll = layerElement.find('div.layer');
            scroll.touchScroll();
        }
        
        var resetScrolling = function(){
            if (!!('ontouchstart' in window)) {
                scroll.touchScroll('setPosition', 0)
            }
        }
    
        var updateScrolling = function() {
            scroll.touchScroll({ scrollHeight: (scroll.height() * 2) - scroll.parent().height() + 230});

			if (options.fixedClose) {
				if(scrollInterval){
					clearInterval(scrollInterval);
				}

				scrollInterval = setInterval(function(){
					if(scroll.touchScroll('getPosition') > 75){
						layerElement.addClass('fixedClose');
					}
					else {
						layerElement.removeClass('fixedClose');
					}
				}, 100);
			}
        }
    }
    
    $.layer = new Layer();
})(jQuery);
