(function ($) {



var $overlay, $cbox, $wrap, $content, $topBorder, $leftBorder, $rightBorder, $bottomBorder, $related, $window, $loaded, $loadingOverlay, $loadingGraphic, $title, $current, $slideshow, $next, $prev, $close,

publicMethod, interfaceHeight, interfaceWidth, loadedHeight, loadedWidth, maxWidth, maxHeight, element, index, settings, open, callback, colorbox = 'colorbox', hover = 'hover',
prev, next, init, load, position, dimensions, slideshow, close,

cbox_open = 'cbox_open', cbox_load = 'cbox_load', cbox_complete = 'cbox_complete', cbox_close = 'cbox_close', cbox_closed = 'cbox_closed',

defaults = {
transition: s5_boxeffect,
speed: 350,
width: false,
height: false,
initialWidth: "100",
initialHeight: "100",
maxWidth: false,
maxHeight: false,
resize: true,
inline: false,
html: false,
iframe: false,
photo: false,
href: false,
title: false,
rel: false,
opacity: 0.3,
preloading: true,
current: "image {current} of {total}",
previous: "previous",
next: "next",
close: "close",
open: false,
overlayClose: true,
slideshow: false,
slideshowAuto: true,
slideshowSpeed: 2500,
slideshowStart: "start slideshow",
slideshowStop: "stop slideshow"
};


function cbox_key(e) {
if (e.keyCode === 37) {
e.preventDefault();
$prev.click();
} else if (e.keyCode === 39) {
e.preventDefault();
$next.click();
}
}
function setSize(size, dimension) {
dimension = dimension === 'x' ? document.documentElement.clientWidth : document.documentElement.clientHeight;
return (typeof size === 'string') ? (size.match(/%/) ? (dimension / 100) * parseInt(size, 10) : parseInt(size, 10)) : size;
}

function isImage(url) {
return settings.photo ? true : url.match(/\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i);
}

function process() {
for (var i in settings) {
if (typeof(settings[i]) === 'function') {
    settings[i] = settings[i].call(element);
}
}
}
$.fn.colorbox = function (options, custom_callback) {
if (this.length) {
this.each(function () {
var data = $(this).data(colorbox) ? $.extend({},
$(this).data(colorbox), options) : $.extend({}, defaults, options);
$(this).data(colorbox, data).addClass("cboxelement");
});
} else {
$(this).data(colorbox, $.extend({}, defaults, options));
}
$(this).unbind("click.colorbox").bind("click.colorbox", function (event) {
element = this;
settings = $(element).data(colorbox);
process();//process settings functions
$().bind("keydown.cbox_close", function (e) {
if (e.keyCode === 27) {
e.preventDefault();
$close.click();
}
});
if (settings.overlayClose === true) {
$overlay.css({"cursor": "pointer"}).one('click', close);
}


element.blur();
callback = custom_callback || false;
var rel = settings.rel || element.rel;
if (rel && rel !== 'nofollow') {
$related = $('.cboxelement').filter(function () {
var relRelated = $(this).data(colorbox).rel || this.rel;
return (relRelated === rel);
});
index = $related.index(element);
if (index < 0) { 
$related = $related.add(element);
index = $related.length - 1;
}
} else {
$related = $(element);
index = 0;
}
if (!open) {
$.event.trigger(cbox_open);
$close.html(settings.close);
$overlay.css({"opacity": settings.opacity}).show();
open = true;
position(setSize(settings.initialWidth, 'x'), setSize(settings.initialHeight, 'y'), 0);
if ($.browser.msie && $.browser.version < 7) {
$window.bind("resize.cboxie6 scroll.cboxie6", function () {
$overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()});
}).trigger('scroll.cboxie6');
}
}
slideshow();
load();
event.preventDefault();
});
if (options && options.open) {
$(this).triggerHandler('click.colorbox');
}
return this;
};


init = function () {
function $div(id) {
return $('<div id="cbox' + id + '"/>');
}
$window = $(window);
$cbox = $('<div id="colorbox"/>');
$overlay = $div("Overlay").hide();
$wrap = $div("Wrapper");
$content = $div("Content").append(
$loaded = $div("LoadedContent").css({width: 0, height: 0}),
$loadingOverlay = $div("LoadingOverlay"),
$loadingGraphic = $div("LoadingGraphic"),
$title = $div("Title"),
$current = $div("Current"),
$slideshow = $div("Slideshow"),
$next = $div("Next"),
$prev = $div("Previous"),
$close = $div("Close")
);
$wrap.append( 
$('<div/>').append(
$div("TopLeft"),
$topBorder = $div("TopCenter"),
$div("TopRight")
),
$('<div/>').append(
$leftBorder = $div("MiddleLeft"),
$content,
$rightBorder = $div("MiddleRight")
),
$('<div/>').append(
$div("BottomLeft"),
$bottomBorder = $div("BottomCenter"),
$div("BottomRight")
)
).children().children().css({'float': 'left'});
$('body').prepend($overlay, $cbox.append($wrap));
if ($.browser.msie && $.browser.version < 7) {
$overlay.css('position', 'absolute');
}

$content.children()
.addClass(hover)
.mouseover(function () { $(this).addClass(hover); })
.mouseout(function () { $(this).removeClass(hover); })
.hide();

interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6
interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
loadedHeight = $loaded.outerHeight(true);
loadedWidth = $loaded.outerWidth(true);

$cbox.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth}).hide();

$next.click(next);
$prev.click(prev);
$close.click(close);

$content.children().removeClass(hover);
};
position = function (mWidth, mHeight, speed, loadedCallback) {
var winHeight = document.documentElement.clientHeight,
posTop = winHeight / 2 - mHeight / 2,
posLeft = document.documentElement.clientWidth / 2 - mWidth / 2,
animate_speed;

if (mHeight > winHeight) { posTop -=(mHeight - winHeight); }
if (posTop < 0) { posTop = 0; } 
if (posLeft < 0) { posLeft = 0; }
posTop += $window.scrollTop();
posLeft += $window.scrollLeft();
mWidth = mWidth - interfaceWidth;
mHeight = mHeight - interfaceHeight;

animate_speed = ($cbox.width() === mWidth && $cbox.height() === mHeight) ? 0 : speed;


$wrap[0].style.width = $wrap[0].style.height = "9999px";
function modalDimensions (that) {
$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width;
$loadingGraphic[0].style.height = $loadingOverlay[0].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;
}
$cbox.dequeue().animate({height:mHeight, width:mWidth, top:posTop, left:posLeft}, {duration: animate_speed,
complete: function(){
modalDimensions(this);

$wrap[0].style.width = (mWidth+interfaceWidth) + "px";
$wrap[0].style.height = (mHeight+interfaceHeight) + "px";
if (loadedCallback) {loadedCallback();}
},
step: function(){
modalDimensions(this);
}
});
};
dimensions = function (object) {
if(!open){ return; }
$window.unbind('resize.cbox_resize');
var width, height, topMargin, prev, prevSrc, next, nextSrc, photo,
speed = settings.transition==="none" ? 0 : settings.speed;
$loaded.remove();
$loaded = $(object);
function getWidth(){
if(settings.width){
width = maxWidth;
} else {
width = maxWidth && maxWidth < $loaded.width() ? maxWidth : $loaded.width();
}
return width;
}
function getHeight(){
if(settings.height){
height = maxHeight;
} else {
height = maxHeight && maxHeight < $loaded.height() ? maxHeight : $loaded.height();
}
return height;
}
$loaded.hide().appendTo('body')
.attr({id:'cboxLoadedContent'})
.css({width:getWidth()})
.css({height:getHeight()})//sets the height independently from the width in case the new width influences the value of height.
.prependTo($content);

if ($.browser.msie && $.browser.version < 7) {
$('select:not(#colorbox select)').filter(function(){
return $(this).css('visibility') !== 'hidden';
}).css({'visibility':'hidden'}).one(cbox_close, function(){
$(this).css({'visibility':'inherit'});
});
}
photo = $('#cboxPhoto')[0];
if (photo && settings.height) {
topMargin = (height - parseInt(photo.style.height, 10))/2;
photo.style.marginTop = (topMargin > 0 ? topMargin : 0)+'px';
}
function setPosition (s) {
var mWidth = width+loadedWidth+interfaceWidth,
mHeight = height+loadedHeight+interfaceHeight;
position(mWidth, mHeight, s, function(){
if (!open) { return; }
if ($.browser.msie) {
if( photo ){$loaded.fadeIn(100);}
$cbox.css('filter','');
}
$content.children().show();

$('#cboxIframeTemp').after("<iframe id='cboxIframe' name='iframe_"+new Date().getTime()+"' frameborder=0 src='"+(settings.href || element.href)+"' />").remove();
$loadingOverlay.hide();
$loadingGraphic.hide();
$slideshow.hide();
if ($related.length>1) {
$current.html(settings.current.replace(/\{current\}/, index+1).replace(/\{total\}/, $related.length));
$next.html(settings.next);
$prev.html(settings.previous);
$().unbind('keydown', cbox_key).bind('keydown', cbox_key);
if(settings.slideshow){
$slideshow.show();
}
} else {
$current.hide();
$next.hide();
$prev.hide();
}
$title.html(settings.title || element.title);
$.event.trigger(cbox_complete);
if (callback) {
callback.call(element);
}
if (settings.transition === 'fade'){
$cbox.fadeTo(speed, 1, function(){
if($.browser.msie){$content.css('filter','');}
});
}
$window.bind('resize.cbox_resize', function(){
position(mWidth, mHeight, 0);
});
});
}
if (settings.transition === 'fade') {
$cbox.fadeTo(speed, 0, function(){setPosition(0);});
} else {
setPosition(speed);
}

if (settings.preloading && $related.length>1) {
prev = index > 0 ? $related[index-1] : $related[$related.length-1];
next = index < $related.length-1 ? $related[index+1] : $related[0];
nextSrc = $(next).data(colorbox).href || next.href;
prevSrc = $(prev).data(colorbox).href || prev.href;
if(isImage(nextSrc)){
$('<img />').attr('src', nextSrc);
}
if(isImage(prevSrc)){
$('<img />').attr('src', prevSrc);
}
}
};
load = function () {
var height, width, href, loadingElement;
element = $related[index];
settings = $(element).data(colorbox);

process();
$.event.trigger(cbox_load);

height = settings.height ? setSize(settings.height, 'y') - loadedHeight - interfaceHeight : false;
width = settings.width ? setSize(settings.width, 'x') - loadedWidth - interfaceWidth : false;
href = settings.href || element.href;
$loadingOverlay.show();
$loadingGraphic.show();
$close.show();

if(settings.maxHeight){
maxHeight = settings.maxHeight ? setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight : false;
height = height && height < maxHeight ? height : maxHeight;
}
if(settings.maxWidth){
maxWidth = settings.maxWidth ? setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth : false;
width = width && width < maxWidth ? width : maxWidth;
}
maxHeight = height;
maxWidth = width;
if (settings.inline) {
$('<div id="cboxInlineTemp" />').hide().insertBefore($(href)[0]).bind(cbox_load+' '+cbox_close, function(){
$loaded.children().insertBefore(this);
$(this).remove();
});
dimensions($(href).wrapAll('<div/>').parent());
} else if (settings.iframe) {
dimensions(
$("<div><div id='cboxIframeTemp' /></div>")
);//timestamp to prevent caching.
} else if (settings.html) {
dimensions(
$('<div/>').html(settings.html)
);
} else if (isImage(href)){
loadingElement = new Image();
loadingElement.onload = function(){
loadingElement.onload = null;
if((maxHeight || maxWidth) && settings.resize){
var width = this.width,
height = this.height,
percent = 0,
that = this,
setResize = function(){
height += height * percent;
width += width * percent;
that.height = height;
that.width = width;
};
if( maxWidth && width > maxWidth ){
percent = (maxWidth - width) / width;
setResize();
}
if( maxHeight && height > maxHeight ){
percent = (maxHeight - height) / height;
setResize();
}
}
dimensions($("<div />").css({width:this.width, height:this.height}).append($(this).css({width:this.width, height:this.height, display:"block", margin:"auto", border:0}).attr('id', 'cboxPhoto')));
if($related.length > 1){
$(this).css({cursor:'pointer'}).click(next);
}
if($.browser.msie && $.browser.version == 7){
this.style.msInterpolationMode='bicubic';
}
};
loadingElement.src = href;
} else {
$('<div />').load(href, function(data, textStatus){
if(textStatus === "success"){
dimensions($(this));
} else {
dimensions($("<p>Request unsuccessful.</p>"));
}
});
}
};
next = function () {
index = index < $related.length-1 ? index+1 : 0;
load();
};
prev = function () {
index = index > 0 ? index-1 : $related.length-1;
load();
};
slideshow = function () {
var stop, timeOut, className = 'cboxSlideshow_';
$slideshow.bind(cbox_close, function(){
clearTimeout(timeOut);
$slideshow.unbind();
});
function start(){
$slideshow
.text(settings.slideshowStop)
.bind(cbox_complete, function(){
timeOut = setTimeout(next, settings.slideshowSpeed);
})
.bind(cbox_load, function(){
clearTimeout(timeOut);
}).one("click", function(){
stop();
$(this).removeClass(hover);
});
$cbox.removeClass(className+"off").addClass(className+"on");
}
stop = function(){
clearTimeout(timeOut);
$slideshow
.text(settings.slideshowStart)
.unbind(cbox_complete+' '+cbox_load)
.one("click", function(){
start();
timeOut = setTimeout(next, settings.slideshowSpeed);
$(this).removeClass(hover);
});
$cbox.removeClass(className+"on").addClass(className+"off");
};
if(settings.slideshow && $related.length>1){
if(settings.slideshowAuto){
start();
} else {
stop();
}
}
};
close = function () {
$.event.trigger(cbox_close);
open = false;
$().unbind('keydown', cbox_key).unbind("keydown.cbox_close");
$window.unbind('resize.cbox_resize resize.cboxie6 scroll.cboxie6');
$overlay.css({cursor:'auto'}).fadeOut('fast');
$content.children().hide();
$cbox
.stop(true, false)
.removeClass()
.fadeOut('fast', function(){
$loaded.remove();
$cbox.css({'opacity':1});
$.event.trigger(cbox_closed);
});
};
publicMethod = $.fn.colorbox;
publicMethod.init = init;
publicMethod.next = next;
publicMethod.prev = prev;
publicMethod.close = close;
publicMethod.load = load;
publicMethod.position = position;
publicMethod.dimensions = dimensions;
publicMethod.element = function(){ return element; };
publicMethod.settings = defaults;
$(function () {
init();
});
}(jQuery));

