/*
A lightbox for html content
Borrows from jquery.lightbox

Todo: 
- Don't toggle visibility on bleeding elements already hidden for some other reason.

*/




(function($) {
	$.fn.htmlbox = function(config) {

		config = $.extend({
			// Configuration related to overlay
			overlayColor: '#000',
			overlayOpacity:	0.1,
			containerBorderSize: 10,
			containerResizeSpeed: 400,
			width: null, // if null, auto-size to fit content
			height: null, // ditto
			prevCaption: null, // if null, grab caption from a-title
			nextCaption: null, // ditto
			top: null, // force top position instead of vertically centering
			navigation: 'bullets', // 'bullets' or 'text'
			zoomOrigin: true, // animate zoom from clicked link instead of center of screen
			crossfade: '#htmlbox_content' // jquery-query. Default is to fade entire htmlbox_content div
		}, config);
		

		var jq = this; // This, in this context, refer to jQuery object
        var pages = []
        var captions = []
        var curr_id = false
        var showing = false

        function get_id(link) {
            // eg <a href="#page1">test</a>
            var url = $(link).attr('href')
            if(url && url.indexOf('#') !== -1) {
                return url.substr(url.indexOf('#'))
            }
        }

		function _onclick(e) {
		    if(get_id(this)) {
    			init(this);
    			return false; // prevent default (following the href)
			}
		}


		
		/**
		 * Create and add dom elements. Attach event handlers. Show first page.
		 * Reset "pages" and "page"
		 */
		function init(link) {
			// Hide bleeding elements
			$('embed, object, select').css({ 'visibility' : 'hidden' });
			
			// Add dom
			// Apply the HTML markup into body tag
            // $('body').append('' +
            //              '<div id="htmlbox_overlay"></div>' +
            //              '<div id="htmlbox">' + 
            //                  '<div id="htmlbox_content"></div>' +
            //                  '<div id="htmlbox_nav">' + 
            //                      '<div id="htmlbox_status"></div>' +
            //                      '<div id="htmlbox_close"></div>' +
            //                      '<a id="htmlbox_prev">&nbsp;</a>' + 
            //                      '<a id="htmlbox_next">&nbsp;</a>' + 
            //                  '</div>' +
            //              '</div>');

            $(document).keydown(function(e) {
				if(e.keyCode == 27) {
				    hide(link)
				}
			});

			$('body').append(['',
			    '<div id="htmlbox_overlay"></div>',
    			'<div id="htmlbox">',  
    			    '<div id="htmlbox_content"></div>', 
    			    '<div id="htmlbox_nav">',
		                '<div id="htmlbox_status"></div>',
		                '<div id="htmlbox_prev">',
		                    '<a></a>',
		                '</div>',
		                '<span id="htmlbox_bullets"></span>',
		                '<div id="htmlbox_next">',
    		                '<a></a>',
    		            '</div>',
		                '<div id="htmlbox_close"></div>',
		            '</div>',
    			'</div>'                        
            ].join(''))
            
            			
    		
    		function overlay_size() {
    		    return [
    		        Math.max($(document.body).width(), $(window).width()), 
    		        Math.max($(document.body).height(), $(window).height()), 
    		    ]
    		}
    		
    		
			// Show overlay
			var size = overlay_size()
			$('#htmlbox_overlay').css({
				backgroundColor: config.overlayColor,
				opacity: config.overlayOpacity,
				width: size[0],
				height: size[1]
			}).fadeIn();

			// Attach click listeners
			$('#htmlbox_overlay, #htmlbox_close').click(function() {
				hide(link);
				return false; // <-- remove this?
			});
			$('#htmlbox').click(function(e) {
				e.stopPropagation();
			});
			
			// Redraw on window resize
			$(window).resize(function() {
                var size = overlay_size()
                $('#htmlbox_overlay').css({
                    width: size[0],
                    height: size[1]
                }) 
                $('#htmlbox').center({top: config.top})
			});			
            
            


			// populate pages and nav bar
			pages = []
			//next = $('#htmlbox_next')
			var i = 0
			$.each(jq, function() {
			    var id = get_id(this)
			    if(id) {
    			    pages.push(id)
    			    captions.push(this.title)
    			    if(config.navigation == 'bullets') {
                        // $('<a id="htmlbox_bullet'+i+'" class="htmlbox_bullet" href="'+id+'">&nbsp;</a>').insertBefore(next)
                        $('#htmlbox_bullets').append('<a id="htmlbox_bullet'+i+'" class="htmlbox_bullet" href="'+id+'">&nbsp;</a>')
    			    }
    			    i++
    			}
			})
			


								
			$('.htmlbox_bullet, #htmlbox_prev a, #htmlbox_next a').click(function(e) {
			    show(this)
			    return false
		    })

			show(link)
			
			// Call the function that prepares image exibition
			//_set_image_to_view();
		}
		
		function show(link) {
		    var id = get_id(link)
		    var visible = $('#htmlbox').length
		    var html = $(id).outerHTML() 
		    var fixed_size = (config.width && config.height)
		    
		    if(fixed_size) {
		        var w =  config.width, h = config.height
		    }
		    else {
                // var div = $('<div style="float: left"></div>').appendTo(document.body)
                // $(div).html(html)
                // debugger
                // var w = $(div).outerWidth(), h = $(div).outerHeight()
                // $(div).remove()
                // console.log('w', w, 'h', h)
                var w = $(id).outerWidth(), h = $(id).outerHeight()
		    }
		    
		    // set height of htmlbox_content
		    

            
		    // show and zoom
		    if(!showing) {
		        if(config.zoomOrigin) {
		            // downsize and position the htmlbox to the same pos+size as link
		            var l = $(link)
		            $('#htmlbox').css({
		                width: l.width(), 
		                height: l.height(), 
		                left: l.offset().left,
		                top: l.offset().top
		            })
		        }
		        else {
		            // downsize to half size and center
        		    $('#htmlbox').css({width: w * 0.5, height: h * 0.5})
        		    var top = null
        		    if(config.top !== null) {
        		        top = (h*0.25) + config.top
        		    }
        		    $('#htmlbox').center({top: top})
                }
            }
            
            
            if(fixed_size && showing) {
                // just change content (fade out, fade in)
                var after_crossfade = function() {
    		        $('#htmlbox_content').css({height: h}).html(html)
    		        $(config.crossfade).hide()
    		        $('#htmlbox_content').children().show()
    		        $(config.crossfade).fadeIn(300)
    		    }
                if($(config.crossfade).length) {
        		    $(config.crossfade).fadeOut(100, after_crossfade)
    		    }
        		else {
                    after_crossfade()
                }
            }
            else {
                // set/change content and resize box
                // 1. Get the left+top for the full sized box
                var leftTop = $.get_center(w, h)
                var left = leftTop[0]
                var top = config.left === null ? leftTop[1] : config.top 
                
                // var resize_fadein = function() {
                //     $('#htmlbox').css({opacity: 0.0}).animate({opacity:1, width: w, height: h+50, left: left, top: top}, 500, function() {
                // 
                //                      var index = $(pages).index(this) 
                //                      $("#htmlbox_content").addClass('loading')
                //         $('#htmlbox').jshadow()
                //         $('#htmlbox_content').css({height: h})    
                // 
                //                      setTimeout(function() {
                //          $('#htmlbox_content').css({opacity: 0}).html(html).children().show()
                //                          $('#htmlbox_content').animate({opacity: 1}, 300)
                //             $("#htmlbox_content").removeClass('loading')
                //             showing = true
                //                      }, showing ? 1 : 400)
                //     })
                //     
                // }
                
                if(showing) {
                    // $('#htmlbox_content').animate({opacity: 0}, 300, resize_fadein)
                    $('#htmlbox_content').animate({opacity: 0}, 300, function(){
                        $(this).html(html).children().show()
                        
                        $('#htmlbox').animate({width: w, height: h+50, left: left, top: top}, 500, function() {
                            $('#htmlbox').jshadow()
                		    $('#htmlbox_content').css({height: h, opacity: 0}).html(html).children().show()
            		        $('#htmlbox_content').animate({opacity: 1}, 300)
                        })                        
                    })
                    
                }
                else {
                    // $('#htmlbox_content').css({height: h})                    
                    // resize_fadein()                    
                    //$('#htmlbox').css({opacity: 0}).animate({opacity: 1, width: w, height: h+50, left: left, top: top}, 500, function() {
                    $('#htmlbox').animate({width: w, height: h+50, left: left, top: top}, 500, function() {                        
            		    $('#htmlbox_content').addClass('loading')
                        $('#htmlbox').jshadow()
                        $('#htmlbox_content').css({height: h})
                        
                        // invoke onShow
            		    if(config.onShow) {
            		        config.onShow.call(this)
            		    }

            		    setTimeout(function() {
            		        // 1. Add all content (pre-hidden)
            		        $('#htmlbox_content').html(html)
            		        // 2. Hide any crossfade elements
                            $(config.crossfade).hide()
                            // 3. show the rest
                            $('#htmlbox_content').children().show()
                            // 4.fadein crossfade elements
                            $(config.crossfade).fadeIn(500)                                

                            // $('#htmlbox_content').animate({opacity: 1}, 300)
                            //$('#htmlbox_content').fadeOut(1, function() { $(this).fadeIn(500)})
                            $("#htmlbox_content").removeClass('loading')
                            showing = true

                            // invoke onComplete
                		    if(config.onComplete) {
                		        config.onComplete.call(this)
                		    }                                   
            		    }, 400)
                    })                    
    

                }
 

                // 2. Animate width, height, left and top
            }


            // update navigation
            var i = $(pages).index(id)   
            if(config.navigation == 'bullets') {
                // set selected bullet
    		    var cur_i = $(pages).index(curr_id)
    		    $('#htmlbox_bullet'+cur_i).removeClass('selected')
    		    $('#htmlbox_bullet'+i).addClass('selected')
    		    $('#htmlbox_status').html((i+1) + '/' + pages.length)
		
            }
            else  if(config.navigation == 'text') {
		        $('#htmlbox_bullets').html((i+1) + '/' + pages.length)
	        }

		    // position the prev and next
			// doing with w/o js turned up to be extremely complicated
			var wi = $('#htmlbox_bullets').width() / 2
			$('#htmlbox_prev').css({right: ((w/2) + wi + 15)})
			$('#htmlbox_next').css({left: ((w/2) + wi + 15)})

            // Update prev/next captions
            var prev = $('#htmlbox_prev a')
            var next = $('#htmlbox_next a')
            prev.attr({href:pages[i-1]}).html(config.prevCaption || captions[i-1])
            prev.css({visibility: pages[i-1] ? 'visible' : 'hidden'})
            next.attr({href:pages[i+1]}).html(config.nextCaption || captions[i+1])
            next.css({visibility: pages[i+1] ? 'visible' : 'hidden'})
            
		    curr_id = id
		    
		    
		}
		
		function hide(link) {
		    
		    if(config.zoomOrigin) {
    		    var l = $(link)
    		    $('#htmlbox_content').html('')
    		    var css = {
                    width: l.width(), 
                    height: l.height(), 
                    left: l.offset().left,
                    top: l.offset().top,
                    opacity: 0.3
                }
    		    $('#htmlbox').html('').animate(css, 400, function() { 
                    $(this).remove()
                })
            }
            else {
                $('#htmlbox').fadeOut(function() { $(this).remove() })
            }
            $('#htmlbox_overlay').fadeOut(function() { $(this).remove() })

			// show bleeding elements
			$('embed, object, select').css({ 'visibility' : 'visible' });
            
		    showing = false
		    curr_id = false
		    captions = []
		}
		
		return this.unbind('click').click(_onclick);
	};
})(jQuery);




// $.fn.outerHTML = function() {
//     return $( $('<div></div>').html(this.cloneNode(true)) ).html();
// }

jQuery.fn.outerHTML = function(s) {
return (s)
? this.before(s).remove()
: jQuery("<p>").append(this.eq(0).clone()).html();
}

