/*
 * magnifier
 * Copyright(c) 2009, Magic Wand.
 * 
 * This code is licensed under BSD license. Use it as you wish, 
 * but keep this copyright intact.
 */


Magnifier=function(config){this.source_selector='';this.image_src='';this.title=null;this.loader_image='/img/image-loader.gif';this.max_image_win_size=Magnifier.MAX_IMAGE_WIN_SIZE;this.min_load_win_size=Magnifier.MIN_LOAD_WIN_SIZE;this.load_win=null;this.image_win=null;$.extend(this,config);this.preloader=new Magnifier.Preloader({src:this.image_src,callback:this.onLoad,scope:this});}
Magnifier.TITLE_HEIGHT=20;Magnifier.MAX_IMAGE_WIN_SIZE=new Size(800,600);Magnifier.MIN_LOAD_WIN_SIZE=new Size(200,200);Magnifier.prototype={show:function(){if(this.preloader.isLoaded())
this.showImageWin();else
this.showLoadWin();},loadImage:function(){this.showLoadWin();},showLoadWin:function(){var win=this.getLoadWin();win.setFrame(this.getSourceElFrame());win.show('slow');},hideLoadWin:function(speed){if(this.load_win)
this.getLoadWin().hide(speed);},showImageWin:function(){this.getImageWin().showFrom(this.getSourceElFrame(),this.getImageFrame());},hideImageWin:function(){this.getImageWin().hide();},hide:function(){this.hideLoadWin();this.hideImageWin();},getImageFrame:function(){var source_frame=this.getSourceElFrame();var view_frame=Magnifier.Utils.getViewFrame();var source_center=new Offset(source_frame.offset.left+source_frame.size.width/2,source_frame.offset.top+source_frame.size.height/2);var image_frame=new Frame(source_center,this.preloader.getSize());if(image_frame.size.width>this.max_image_win_size.width)
image_frame.size.width=this.max_image_win_size.width;if(image_frame.size.height>this.max_image_win_size.height)
image_frame.size.height=this.max_image_win_size.height;image_frame.size.height+=this.getImageWin().getTitleHeight();if(image_frame.size.width>view_frame.size.width)
image_frame.size.width=view_frame.size.width;if(image_frame.size.height>view_frame.size.height)
image_frame.size.height=view_frame.size.height;image_frame.offset.sub(image_frame.size.width/2,image_frame.size.height/2);if(image_frame.getRight()>view_frame.getRight())
image_frame.offset.sub(image_frame.getRight()-view_frame.getRight(),0);if(image_frame.getBottom()>view_frame.getBottom())
image_frame.offset.sub(0,image_frame.getBottom()-view_frame.getBottom());if(image_frame.offset.left<view_frame.offset.left)
image_frame.offset.left=view_frame.offset.left;if(image_frame.offset.top<view_frame.offset.top)
image_frame.offset.top=view_frame.offset.top;return image_frame;},getLoadWin:function(){if(!this.load_win)
this.load_win=new Magnifier.Win.Loader({title:this.title,loader_image:this.loader_image,on_cancel:this.onCancel,on_show:this.onShowLoadWin,scope:this});return this.load_win;},getImageWin:function(){if(!this.image_win)
this.image_win=new Magnifier.Win.Image({title:this.title,src:this.image_src,on_close:this.onClose,scope:this});return this.image_win;},getSourceElFrame:function(){var frame=new Frame(this.getSourceElOffset(),this.getSourceElSize());frame.size.add(0,Magnifier.TITLE_HEIGHT);if(frame.size.width>=this.min_load_win_size.width&&frame.size.height>=this.min_load_win_size.height)
return frame;frame.offset.add(frame.size.width/2,frame.size.height/2);if(frame.size.width<this.min_load_win_size.width)
frame.size.width=this.min_load_win_size.width;if(frame.size.height<this.min_load_win_size.height)
frame.size.height=this.min_load_win_size.height;frame.offset.sub(frame.size.width/2,frame.size.height/2);return frame;},getSourceElOffset:function(){var offset=new Offset(this.getSourceEl().offset());return offset.sub(Magnifier.Utils.getBodyOffset());},getSourceElSize:function(){var $el=this.getSourceEl();return new Size($el.width(),$el.height());},onLoad:function(preloader){this.hideLoadWin();this.getImageWin().setRealImageSize(preloader.getSize());this.showImageWin();},onCancel:function(){this.preloader.cancel();this.hideLoadWin('normal');},onClose:function(){this.getImageWin().hideTo(this.getSourceElFrame());},onShowLoadWin:function(){this.preloader.load();},getSourceEl:function(){return $(this.source_selector);}}
Magnifier.Utils={getViewFrame:function(){return new Frame(Magnifier.Utils.getViewOffset(),Magnifier.Utils.getViewSize());},getViewSize:function(){var height=document.compatMode=='CSS1Compat'?document.documentElement.clientHeight:document.body.clientHeight;var width=document.compatMode=='CSS1Compat'?document.documentElement.clientWidth:document.body.clientWidth;return new Size(width,height);},getViewOffset:function(){var top=self.pageYOffset||(document.documentElement&&document.documentElement.scrollTop)||(document.body&&document.body.scrollTop);var left=self.pageXOffset||(document.documentElement&&document.documentElement.scrollLeft)||(document.body&&document.body.scrollLeft);return new Offset(left,top);},getBodyOffset:function(){return $('body').offset();}}
Magnifier.Win=function(config){this.frame=new Frame();this.title=null;this.title_height=Magnifier.TITLE_HEIGHT;this.on_show=null;this.scope=null;this.el_selector=null;this.shown=false;this.showing=false;$.extend(this,config);this._init();}
Magnifier.Win.prototype={_init:function(){},show:function(speed){if(this.shown)
return;if(speed){var _this=this;this.getEl().fadeIn(speed,function(){_this.onShow();});}else{this.getEl().show();if(!this.showing)
this.onShow();}},hide:function(speed){if(!this.shown)
return;if(speed){var _this=this;this.getEl().fadeOut(speed,function(){_this.onHide();});}else{this.getEl().hide();this.onHide();}},setOffset:function(left,top){this.frame.setOffset(left,top);this.applyOffset();},setSize:function(width,height){this.frame.setSize(width,height);this.applySize();},setFrame:function(frame){this.frame=frame;this.applyOffset();this.applySize();},applyOffset:function(){this.getEl().css('top',this.frame.offset.top+'px').css('left',this.frame.offset.left+'px');},applySize:function(){this._applyWinSize();this._applyBodySize();},_applyWinSize:function(){this.getEl().width(this.frame.size.width).height(this.frame.size.height);},_applyBodySize:function(){this.getBodyEl().height(this.getBodySize().height).width(this.getBodySize().width);},getBodySize:function(){return this.calcBodySize(this.frame.size);},calcBodySize:function(win_size){return new Size(win_size.width,win_size.height-this.title_height);},getTitleHeight:function(){return this.title_height;},showFrom:function(from,to){this.showing=true;this.setFrame(from);this.show();this._animateWindow(to,this.onShow);},hideTo:function(to){this._animateWindow(to,this.hide);},_animate:function(el,to,callback){var _this=this;el.animate({top:to.offset.top+'px',left:to.offset.left+'px',width:to.size.width+'px',height:to.size.height+'px'},'fast',function(){if(callback)
callback.call(_this);});},_animateBody:function(frame_target){var body_frame=new Frame(new Offset(),this.calcBodySize(frame_target.size));this._animate(this.getBodyEl(),body_frame);},_animateWindow:function(to,callback){this._animate(this.getEl(),to,function(){this.setFrame(to);if(callback)
callback.call(this);});this._animateBody(to);},onShow:function(){this.showing=false;this.shown=true;if(this.on_show)
this.on_show.call(this.scope?this.scope:this,this);},onHide:function(){this.shown=false;},setOverflowBody:function(state){this.getBodyEl().css('overflow',state?'scroll':'hidden');},getEl:function(){if(!this.el_selector)
this.el_selector=this._createElem();return $(this.el_selector);},getBodyEl:function(){return $('.body',this.getEl());},getTitleEl:function(){return $('.title',this.getEl());},_createElem:function(){var $el=$('<div class="magnify_win" style="display: none; position: absolute;"></div>').appendTo('body');this._initElem($el);return $el.getIdSelector();},_initElem:function($el){this._createContainer($el);},_createContainer:function($el){var $container_el=$('<div class="container" style="position: relative; width: 100%; height: 100%;"></div>').appendTo($el);this._initContainer($container_el);},_initContainer:function($el){this._createBody($el);this._createTitle($el);},_createBody:function($el){var $body_el=$('<div class="body" style="position: relative; width: 100%;"></div>').appendTo($el);this._initBody($body_el);},_initBody:function($el){},_createTitle:function($el){var $title_el=$('<div class="title" style="position: relative; overflow: hidden; width: 100%;"><div class="title_text"></div></div>').appendTo($el);this._initTitle($title_el);},_initTitle:function($el){$('.title_text',$el).html(this.title?this.title:'&#160;');}}
Magnifier.Win.Loader=function(config){this.loader_image='/i/image-loader.gif';this.on_cancel=null;Magnifier.Win.Loader.superclass.constructor.call(this,config);}
utils.extend(Magnifier.Win.Loader,Magnifier.Win,{_initBody:function($el){$el.css('overflow','hidden');$('<table width="100%" height="100%"><tr><td style="text-align: center; vertical-align: middle;"><img src="'+this.loader_image+'" alt="loading..."/></td></tr></table>').appendTo($el);$('img',$el).css('cursor','pointer').bind('click',{target:this},this.onCancel);},onCancel:function(e){e.data.target.cancel();},cancel:function(){if(this.on_cancel)
this.on_cancel.call(this.scope?this.scope:this,this);}});Magnifier.Win.Image=function(config){this.src=false;this.real_image_size=new Size();this.on_close=null;this.scope=null;this.closed=true;Magnifier.Win.Image.superclass.constructor.call(this,config);}
utils.extend(Magnifier.Win.Image,Magnifier.Win,{setRealImageSize:function(width,height){this.real_image_size=new Size(width,height);},show:function(speed){this.setImageToFillMode();Magnifier.Win.Image.superclass.show.call(this,speed);},close:function(){if(this.closed)
return;this.closed=true;this.setImageToFillMode();if(this.on_close)
this.on_close.call(this.scope?this.scope:this,this);},_applyBodySize:function(){Magnifier.Win.Image.superclass._applyBodySize.call(this);this._applyImageSize();},_applyImageSize:function(){this.getImgEl().width(this.getBodySize().width).height(this.getBodySize().height);},_animateBody:function(frame_target){Magnifier.Win.Image.superclass._animateBody.call(this,frame_target);var body_frame=new Frame(new Offset(),this.calcBodySize(frame_target.size));this._animate(this.getImgEl(),body_frame,this.onEndImageAnimation);},onClose:function(e){e.data.target.close();},onEndImageAnimation:function(){this.closed=false;Magnifier.Win.Image.superclass.onShow.call(this);this.setImageToOverflowMode();},setImageToOverflowMode:function(){var body_size=this.getBodySize();if(this.real_image_size.width>body_size.width||this.real_image_size.height>body_size.height){this.setOverflowBody(true);this.getImgEl().width(this.real_image_size.width).height(this.real_image_size.height);}},setImageToFillMode:function(){this.setOverflowBody(false);this._applyImageSize();},_initBody:function($el){$('<img src="'+this.src+'" alt="" title="кликните, чтобы закрыть"/>').appendTo($el).css('cursor','pointer').bind('click',{target:this},this.onClose);},getImgEl:function(){return $('img',this.getBodyEl());}});Magnifier.Manager=function(){this.magnifiers=[];}
Magnifier.Manager._instance=null;Magnifier.Manager.instance=function(){if(!Magnifier.Manager._instance)
Magnifier.Manager._instance=new Magnifier.Manager();return Magnifier.Manager._instance;}
Magnifier.Manager.prototype={get:function(id){return this.magnifiers[id];},add:function(id,magnifier){this.magnifiers[id]=magnifier;}}
Magnifier.Preloader=function(config){this.src=null;this.callback=null;this.scope=null;this.loaded=false;this.size=new Size();this.selector=null;$.extend(this,config);}
Magnifier.Preloader.prototype={load:function(){this.loaded=false;this.getImgEl().attr('src',this.src);},isLoaded:function(){return this.loaded;},getSize:function(){return this.size;},onLoad:function(e){var _this=e.data.target;_this.size.setup(this.width,this.height);_this.loaded=true;_this.removeEl();if(_this.callback)
_this.callback.call(_this.scope?_this.scope:_this,_this);},cancel:function(){this.removeEl();},removeEl:function(){if(!this.selector)
return;this.getImgEl().unbind('load',this.onLoad);this.getEl().remove();this.selector=null;},getEl:function(){if(!this.selector)
this.selector=this._createPreloadImg();return $(this.selector);},getImgEl:function(){return $('img',this.getEl());},_createPreloadImg:function(){var $el=$('<div style="position: absolute; top: -10px; left: -10px; width: 1px; height: 1px; overflow: hidden;"></div>');var $img=$('<img>').bind('load',{target:this},this.onLoad);return $el.append($img).appendTo('body').getIdSelector();}}
function enlarge(link_elem){var $src_elem=$('img',link_elem);if(!$src_elem.length)
$src_elem=$(link_elem);var id=$src_elem.generateId().attr('id');var magnifier=Magnifier.Manager.instance().get(id);if(!magnifier)
Magnifier.Manager.instance().add(id,magnifier=new Magnifier({source_selector:$src_elem.getIdSelector(),image_src:$(link_elem).attr('href'),title:$src_elem.attr('title')}));magnifier.show();return false;}
$.fn.magnifier=function(pattern){return this.each(function(){if(this.src.indexOf(pattern)>=0){var $img=$(this);var id=$img.generateId().attr('id');var magnifier=new Magnifier({source_selector:$img.getIdSelector(),image_src:this.src.replace(pattern,''),title:$img.attr('title')});Magnifier.Manager.instance().add(id,magnifier);$img.addClass('magnifier').click(function(){magnifier.show();});}});}

