(function($) {
    $.fn.BadBox = function(settings) {
        var fn = new Object();

        if (settings && settings.height) settings.providedDimensions = true;

        settings = jQuery.extend({
            width: 640,
            height: 480,
            setup: false,
            btnBar: null,
            bgClick: true,
            callback: null,
            image: null,
            html: null,
            id: null,
            movie: null,
            ajaxURL: null,
            ajaxParams: null,
            bgOpacity: 0.5,
            flashVars: null,
            hideFlashInFFMac: true,
            retainContent: true,
            appendId: 'body'
        }, settings);

        if (typeof (this) != 'function') { settings.id = this; }

        fn.setup = function() {
            var newHTML = { tag: 'div', id: 'BBContainer', content: [{ tag: 'div', id: 'BBOverlay' }, { tag: 'div', id: 'BBModalOutside', content: { tag: 'div', id: 'BBModalInside', content: [{ tag: 'div', id: 'BBContent' }, { tag: 'div', id: 'BBBtnBar'}]}}] };
            var BBHTML = fn.buildElement(newHTML);
            $(settings.appendId).append(BBHTML);
            if ($.browser.msie && $.browser.version < 7) {
                $('#BBContainer').prepend(fn.buildElement({ tag: 'iframe', id: 'BBIframe', frameborder: 0, tabindex: -1, src: 'javascript:false' }));
                $('#BBOverlay').css('opacity', settings.bgOpacity);
            } else {
                if ((navigator.appVersion.indexOf("Mac") != -1) && (($.browser.mozilla && $.browser.version < 1.9) || $.browser.opera) && settings.hideFlashInFFMac) $('embed').css('visibility', 'hidden');
                //$('#BBOverlay').css('opacity', 0).animate({ opacity: settings.bgOpacity }, 'fast');
                $('#BBOverlay').css('opacity', settings.bgOpacity);
            }
            if (settings.bgClick) {
                $('#BBOverlay').bind('click', fn.removeModal);
            }
            fn.createLoading();
            fn.routeType();
        };

        fn.routeType = function() {
            if (settings.html) {
                fn.displayHTML();
            } else if (settings.image) {
                fn.displayImage();
            } else if (settings.movie) {
                fn.displayMovie();
            } else if (settings.ajaxURL) {
                fn.getAJAX();
            } else if (settings.id) {
                fn.displayId();
                //			} else if (settings.mapTo) {
                //				fn.displayMap();
            } else if (settings.flash) {
                fn.displayFlash();
            } else if (settings.iframe) {
                fn.displayIframe();
            }
        };

        fn.revealBtnBar = function(callback) {
            if (settings.btnBar) {
                if (!settings.setup) {
                    $('#BBBtnBar').append(settings.btnBar)
						.css('bottom', '-' + fn.btnBarSize() + 'px')
                        .animate({ bottom: 0 }, 'fast');
                    settings.setup = true;
                    if (callback) {
                        callback.call();
                    }
                }
            }
        };

        fn.createLoading = function() {
            if (!($.browser.msie && $.browser.version < 7)) {
                $('#BBModalOutside').css('opacity', 1); //.animate({ opacity: 1 }, 'fast');
            }
            $('#BBContent').append(fn.buildElement({ tag: 'div', id: 'BBLoading', content: { tag: 'div', id: 'BBLoadingImage' }, text: 'Loading' }));
        };

        fn.displayHTML = function() {
            fn.removeLoading();
            fn.resizeModal(settings.width, settings.height, function() {
                $('#BBContent').append(settings.html);
                fn.revealBtnBar();
            });
        };

        fn.displayId = function() {
            var placeHolder = '<div id="badBoxPlaceHolder" style="display:none;"></div>';
            var element = typeof (settings.id) == 'string' ? $('#' + settings.id) : settings.id;
            element.before(placeHolder);
            if (!settings.providedDimensions) {
                var elementHeight = element.css('height');
                settings.height = parseInt(elementHeight.slice(0, elementHeight.length - 2));
                var elementWidth = element.css('width');
                settings.width = parseInt(elementWidth.slice(0, elementWidth.length - 2));
            }
            fn.removeLoading();
            fn.resizeModal(settings.width, settings.height, function() {
                $('#BBContent').append(element);
                element.show();
                fn.revealBtnBar();
            });
        };

        fn.displayImage = function() {
            $(settings.appendId).append(fn.buildElement({ tag: 'img', id: 'BBModalImage', src: settings.image, style: 'position:absolute;top:0;left:0' }));
            $('#BBModalImage').css('position', 'absolute')
				.bind('load', function() {
				    if (settings.imageRel) {
				        settings.btnBar = [fn.buildElement({ tag: 'span', id: 'BBImageCount' }),
												fn.buildElement({ tag: 'a', id: 'BBPrev', href: '#', className: 'btn', content: { tag: 'span', text: 'Previous'} }),
												fn.buildElement({ text: ' ' }),
												fn.buildElement({ tag: 'a', id: 'BBClose', href: '#', className: 'btn', content: { tag: 'span', text: 'Close'} }),
												fn.buildElement({ text: ' ' }),
												fn.buildElement({ tag: 'a', id: 'BBNext', href: '#', className: 'btn', content: { tag: 'span', text: 'Next'} })
											];
				        settings.curIndex = $('.badBox').index(settings.currentImage.get(0));
				    } else {
				        settings.btnBar = [
												fn.buildElement({ tag: 'a', id: 'BBClose', href: '#', className: 'btn', content: { tag: 'span', text: 'Close'} }),
												fn.buildElement({ text: ' ' })
											];
				    }
				    fn.removeLoading();
				    fn.resizeModal($(this).width(), $(this).height(), function() {
				        fn.showHideButtons();
				        $('#BBModalImage').appendTo($('#BBContent'))
							.css('position', 'relative')
								.hide()
									.css('opacity', 1)
										.fadeIn('fast');
				        var bindActions = function() {
				            $('#BBPrev').click(function(event) {
				                settings.curIndex--;
				                fn.changeImage();
				                return false;
				            });
				            $('#BBNext').click(function(event) {
				                settings.curIndex++;
				                fn.changeImage();
				                return false;
				            });
				            $('#BBClose').click(fn.removeModal);
				            fn.showHideButtons();
				        };
				        fn.revealBtnBar(bindActions);
				    });
				});
        };

        fn.changeImage = function() {
            settings.currentImage = $($('.badBox').get(settings.curIndex));
            $('#BBPrev, #BBNext, #BBClose, #BBImageCount').hide();
            settings.image = settings.currentImage.attr('href');
            $('#BBModalImage').remove();
            fn.createLoading();
            fn.displayImage();
        };

        //		fn.displayMap = function() {
        //			settings.btnBar = 	[	fn.buildElement({tag:'span', id:'BBImageCount'}),
        //									fn.buildElement({tag:'a', id:'BBFullMap', href:'#', className:'btn', content:{tag:'span', text:'Full Map'}}),
        //									fn.buildElement({text:' '}),
        //									fn.buildElement({tag:'a', id:'BBClose', href:'#', className:'btn', content:{tag:'span', text:'Close'}})
        //								];
        //			fn.removeLoading();
        //			fn.resizeModal(settings.width, settings.height, function() {
        //				$('#BBContent').append(fn.buildElement({tag:'div', id:'BBMap'}));
        //				var BBMap = $('#BBMap');
        //				BBMap.width(settings.width).height(settings.height);
        //				BBMap.jmap({language:"en"});
        //				BBMap.jmap({mapCenter: [34.033614,-118.395081], mapControlSize: "large", mapEnableScrollZoom: true});
        //				BBMap.createMarkerManager();
        //				BBMap.createGeoCache();
        //				var fullMap = new String();
        //				var lat, lng, toAddress, fromAddress;
        //				toAddress = settings.mapTo.replace(/ /g,"+");
        //				var geocoder = new GClientGeocoder();
        //				geocoder.getLatLng(settings.mapTo, function(point) {
        //					lat = point.lat();
        //					lng = point.lng();
        //				});
        //				if (!settings.mapFrom) {
        //					var testing = $('#BBMap').searchAddress({
        //						address: settings.mapTo,
        //						cache: $.jmap.GGeoCache
        //					});
        //					fullMap = 'http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=' + toAddress + '&sll=&sspn=0.006588,0.007596&ie=UTF8&ll=' + lat + ',' + lng + '&spn=&z=15&iwloc=addr&om=1';
        //				} else {
        //					$('#BBMap').searchDirections({
        //	        			fromAddress: settings.mapFrom,
        //	        			toAddress: settings.mapTo,
        //	        			directionsPanel: "directions"
        //					});
        //					var fromAddress = settings.mapFrom.replace(/ /g,"+");
        //					fullMap = 'http://maps.google.com/maps?f=d&hl=en&geocode=&time=&date=&ttype=&saddr=' + fromAddress + '&daddr=' + toAddress + '&sll=' + lat + ',' + lng + '&sspn=&ie=UTF8&z=5&om=1';
        //				}
        //				var bindActions = function() {
        //					$('#BBClose').click(fn.removeModal);
        //					$('#BBFullMap').click(function() {
        //						window.open(fullMap,'gMapWindow','width=1024,height=768,resizable=yes,resizable=yes');
        //						return false;
        //					});
        //				};
        //				fn.revealBtnBar(bindActions);
        //			});
        //		};

        fn.displayMovie = function() {
            settings.btnBar = [
									fn.buildElement({ tag: 'a', id: 'BBClose', href: '#', className: 'btn', content: { tag: 'span', text: 'Close'} }),
									fn.buildElement({ text: ' ' })
								];
            fn.removeLoading();
            var callback = function() {
                $('#BBContent').InsertObject({
                    width: settings.width,
                    height: settings.height,
                    src: settings.movie
                });
                var bindActions = function() {
                    $('#BBClose').click(fn.removeModal);
                };
                fn.revealBtnBar(bindActions);
            };
            fn.resizeModal(settings.width, settings.height, callback);
        };

        fn.displayFlash = function() {
            settings.btnBar = [
									fn.buildElement({ tag: 'a', id: 'BBClose', href: '#', className: 'btn', content: { tag: 'span', text: 'Close'} }),
									fn.buildElement({ text: ' ' })
								];
            var bindActions = function() {
                $('#BBClose').click(fn.removeModal);
            };
            fn.removeLoading();
            var callback = function() {
                var wmode = 'transparent';
                var bgcolor = '#ffffff';
                if ((navigator.appVersion.indexOf("Mac") != -1) && $.browser.mozilla) {
                    bgcolor = fn.convertToHex($('#BBModalInside').css('background-color'));
                    wmode = 'window';
                }
                $('#BBContent').InsertObject({
                    width: settings.width,
                    height: settings.height,
                    src: settings.flash,
                    flashVars: settings.flashVars,
                    wmode: wmode,
                    bgcolor: bgcolor
                });
                fn.revealBtnBar(bindActions);
            };
            fn.resizeModal(settings.width, settings.height, callback);
        };

        fn.convertToHex = function(strBGColor) {
            var DecToHex = function(intDec, intPlaces) {
                var strHexDef = new String("0123456789ABCDEF");

                var strHex = strHexDef.substr(intDec & 15, 1);

                while (intDec > 15) {
                    intDec >>= 4;
                    strHex = strHexDef.substr(intDec & 15, 1) + strHex;
                }

                for (var intX = strHex.length; intX < intPlaces; intX++) {
                    strHex = '0' + strHex;
                }

                return strHex;
            }

            if (strBGColor.indexOf('rgb(') == 0) {
                var strTempColorAry = strBGColor.replace(/ /g, '').substring(4, strBGColor.length - 1).split(',');
                var strRed = DecToHex(parseInt(strTempColorAry[0]), 2);
                var strGreen = DecToHex(parseInt(strTempColorAry[1]), 2);
                var strBlue = DecToHex(parseInt(strTempColorAry[2]), 2);

                return '#' + strRed + strGreen + strBlue;
            } else {
                return strBGColor.toUpperCase();
            }
        }

        fn.showHideButtons = function() {
            $('#BBImageCount').text(settings.curIndex + 1 + ' of ' + $('.badBox').size()).show();
            settings.curIndex != 0 ? $('#BBPrev').show() : $('#BBPrev').hide();
            settings.curIndex + 1 != $('.badBox').size() ? $('#BBNext').show() : $('#BBNext').hide();
            $('#BBClose').show();
        };

        fn.btnBarSize = function() {
            var paddingTop = $('#BBBtnBar').css('paddingTop');
            var paddingTopLength = paddingTop.length;
            var paddingTopNumber = parseInt(paddingTop.substring(0, paddingTopLength - 2));
            return ($('#BBBtnBar').height() + paddingTopNumber);
        };

        fn.resizeModal = function(width, height, callback) {
            width += fn.getTotalSpacing('Left');
            height += fn.getTotalSpacing('Top');
            if (settings.btnBar) {
                height += fn.btnBarSize();
            }
            $('#BBModalOutside')
                .css('width', width)
                .css('height', height)
                .css('marginLeft', -width / 2)
                .css('marginTop', -height / 2);
//            $('#BBModalOutside').animate({ width: width, marginLeft: -width / 2 }, 'fast', function() {
//                var animObject = {
//                    height: height
//                };
//                if (!($.browser.msie && $.browser.version < 7)) {
//                    animObject.marginTop = (-height / 2);
//                }
//                var speed = 'fast';
//                $('#BBModalOutside').animate(animObject, speed, function() {
                    if (callback) { callback.call() }
//                });
//            });
        };

        fn.getTotalSpacing = function(side) {
            var total = 0;
            var containers = [$('#BBModalOutside'), $('#BBModalInside'), $('#BBContent')];
            var types = ['padding'];
            for (x in containers) {
                for (y in types) {
                    var stringValue = containers[x].css(types[y] + side);
                    var intValue = parseInt(stringValue.substring(0, stringValue.length - 2));
                    if (intValue > 0) { total += intValue }
                }
            }
            return total;
        };

        fn.getAJAX = function() {
            settings.ajaxParams = settings.ajaxParams || null;
            $.get(settings.ajaxURL, settings.ajaxParams, function(data) {
                fn.removeLoading();
                fn.resizeModal(settings.width, settings.height, function() {
                    $('#BBContent').html($(data).html());
                    fn.revealBtnBar();
                });
            });
        };

        fn.displayIframe = function() {
            fn.removeLoading();
            fn.resizeModal(settings.width, settings.height, function() {
                var html = [fn.buildElement({ tag: 'iframe', src: settings.iframe, width: settings.width, height: settings.height, frameborder: 0, frameBorder: 0 })];
                $('#BBContent').append(html);
                fn.revealBtnBar();
            });
        }

        fn.removeLoading = function() {
            $('#BBLoading').remove();
        };

        fn.removeModal = function(e, callback) {
            if (callback) {
                settings.callback = callback;
            }
            if (settings.retainContent && settings.id) $('#badBoxPlaceHolder').before($('#BBContent').children().hide());
            $('#badBoxPlaceHolder').remove();
            if (settings.movie) { document.getElementById('BBContent').innerHTML = ' ' };
            $('#BBContainer, #BBModalImage').remove();
            if ((navigator.appVersion.indexOf("Mac") != -1) && ($.browser.mozilla || $.browser.opera) && settings.hideFlashInFFMac) {
                $('embed').each(function() {
                    $(this).css('visibility', 'visible').width($(this));
                });
            }
            if (settings.callback) {
                settings.callback.call();
            }
            window.closeBadBox = null;
            return false;
        };

        fn.buildElement = function(o) {
            var element = o.tag ? document.createElement(o.tag) : null;
            for (var i in o) {
                switch (i) {
                    case 'tag':
                        break;
                    case 'text':
                        if (element) {
                            element.appendChild(document.createTextNode(o[i]));
                        } else {
                            element = document.createTextNode(o[i]);
                        }
                        break;
                    case 'className':
                        element.setAttribute('className', o[i]);
                        element.setAttribute('class', o[i]);
                        break;
                    case 'content':
                        if (o[i].length) {
                            for (var a = 0; a < o[i].length; a++) {
                                element.appendChild(fn.buildElement(o[i][a]));
                            }
                        } else {
                            element.appendChild(fn.buildElement(o[i]));
                        }
                        break;
                    default:
                        element.setAttribute(i, o[i]);
                        break;
                }
            }
            return element;
        };

        fn.setup.call();
        $.BadBox.close = fn.removeModal;
        window.closeBadBox = fn.removeModal;
    };

    $.BadBox = $.fn.BadBox;

    $(function() {
        $('.badBox').click(function() {
            var imageUrl = $(this).attr('href');
            var imageRel = $(this).attr('rel');
            $.BadBox({ image: imageUrl, imageRel: imageRel, currentImage: $(this) });
            return false;
        });
    });
})(jQuery);

function badBox(o) {$.BadBox(o);};
