    var HashObserver = {
        
        lastState : null,
        
        check : function(sliderArea,sliderSector,sliderTrack,sliderDrag,bigPhoto,bigPhotoReplace,bigPhotoDiv,left,right,imageName,largeImgClass){
            if(this.lastState == window.location.hash){
                return;
            }
            this.lastState = window.location.hash;
            var state;
            if(this.lastState =='#flash'){
                state = 'flash';
            }
            else{
                state = parseInt(this.lastState.substr(1));
            }
            PhotoGallery.init(sliderArea,sliderSector,sliderTrack,sliderDrag,bigPhoto,bigPhotoReplace,bigPhotoDiv,left,right,imageName,largeImgClass);
            PhotoGallery.showPhoto(state);

            return false;
        }
    }

    
    var PhotoGallery ={
        
        list : null,
        photosCollection : {},
        currentPos : null,
        hasFlash : null,
        settings : {},
        photoPath : null,
        device : null,
        
        init: function(sliderArea,sliderSector,sliderTrack,sliderDrag,bigPhoto,bigPhotoReplace,bigPhotoDiv,left,right,imageName,largeImgClass){
          Slider.init(sliderArea,sliderSector,sliderTrack,sliderDrag);
          this.settings = {
              'sliderSector' : $(sliderSector,sliderArea),
              'toLeftI' : $('i',left),
              'toRightI' : $('i',right),
              'bigPhoto' : $(bigPhoto),
              'bigPhotoClass' : bigPhoto,
              'bigPhotoReplace' : $(bigPhotoReplace,bigPhoto),
              'bigPhotoDiv' : $(bigPhotoDiv,bigPhoto),
              'imageName' : $(imageName),
              'largeImg' : $(largeImgClass),
              'largeImgLink' : $(largeImgClass),

          };

        },
        
        showPhoto : function(pos){
            if(!pos){
                this.currentPos = 0;
            }
            else{
                this.currentPos = pos;
            }
            this.setCurrentImg();
            this.hasPrevPhoto();
            this.hasNextPhoto();
        },
       
        getCurrentPhoto : function (){
            if(!(this.currentPos in this.photosCollection)){
                this.downloadToCollection(this.currentPos);
            }

            next = this.hasNextPhoto();
            if(next!== false && !(next in this.photosCollection)){
                this.downloadToCollection(next);
            }

            prev = this.hasPrevPhoto();
            if(prev!== false && !(prev in this.photosCollection)){
                this.downloadToCollection(prev);
            }

            return this.photosCollection[this.currentPos];
        },

        downloadToCollection : function(pos){
            if(pos==='flash'){
                this.photosCollection[pos] = $('#d3');
            }
            else if(pos>=0 && pos<this.list.length){
                var path = this.list[pos]['img_path'];
                    var img = new Image();
                img.src = this.photoPath+path;
                this.photosCollection[pos] = img;
            }
                
        },

        hasPrevPhoto : function(){
            if(this.currentPos>0){
                return this.currentPos-1;
            }

            if(this.currentPos == 0 && this.hasFlash){
                return 'flash';
            }
        
            this.settings.toLeftI.css('visibility','hidden');
            return false;
        },

        hasNextPhoto : function(){
            if(this.hasFlash && this.currentPos == 'flash'){
                return 0;
            }

            if(this.currentPos + 1 < this.list.length){
                return this.currentPos + 1;
            }
            this.settings.toRightI.css('visibility','hidden');
            return false;
        },

        setWidthOfImgDiv : function(img){
            // if flash set div.width = 590, therefore all flash has width = 500;
            if(this.hasFlash && this.currentPos=='flash'){
                 this.settings.bigPhotoDiv.width(705);
            } else {
                 // if image is loaded set div.width = img.width+90 
                 if(img.complete) {
                      this.settings.bigPhotoDiv.width(parseInt(img.width)+90);
                 } else {
                      //if image is not loaded, then are waiting till img will be loaded and set div.width = img.width+90
                      img.onload = function(){
                          PhotoGallery.settings.bigPhotoDiv.width(parseInt(img.width)+90);
                      };
                 }
            }
        },

        setCurrentImg : function(){
            var img = this.getCurrentPhoto();
            var movePos = this.currentPos;
            if(this.currentPos=='flash'){
                if(!swfobject.hasFlashPlayerVersion("1")){ //flash is not installed
                    var error_text = $('#flash-error-text').html();
                    this.settings.bigPhotoReplace.html(error_text);
                }else{
                    $('.pfr-ar-l').hide();
                    $('.pfr-ar','.big-photo-img-div').css('width','10%');
                    this.settings.bigPhotoReplace.html(img);
                    this.settings.bigPhotoReplace.append('<div class = "flash-rotate-text">Вы можете поворачивать 360&deg;&nbsp;обзорное фото модели при помощи мышки</div>');
                }
                movePos=0;
            } else {
                $('.pfr-ar-l').show();
                $('.pfr-ar').css('width','35%');
                this.settings.bigPhotoReplace.html(img);
                movePos = this.currentPos+1;
            }
            this.setWidthOfImgDiv(img);
            this.settings.sliderSector.removeClass('activethumb');
            $('#thumb_'+this.currentPos).parent().addClass('activethumb');
            Slider.move(movePos);
            this.setAddDataToImg();

        },

        setAddDataToImg : function(){
            if(this.currentPos!='flash'){
                this.settings.imageName.text(this.list[this.currentPos]['img_name']);
                if(this.list[this.currentPos]['large_img_path']){
                    this.settings.largeImgLink.attr("href",this.list[this.currentPos]['large_img_path']);
                    this.settings.largeImg.show();
                }
                else {
                    this.settings.largeImg.hide();
                }

            }
            else {
                this.settings.imageName.text('');
                this.settings.largeImg.hide();
            }
        },
    }

    var Slider = {

        area: null,
        sector: null,
        track: null,
        drag: null,
        viewAll: true,
        settings : {},
        instance: null,

        
        init: function(area,sector,track,drag) {
                this.instance = 1;
                this.area = $(area);
                this.sector = $(sector,area);
                this.track = $(track);
                this.drag = $(drag,track);
                this.onResize();

        },

        countParams: function(){
                var sectorCount = this.sector.size();
                var sectorWidth = this.sector.innerWidth();
                var halfSectorWidth = Math.floor(sectorWidth/2);
                var areaWidth = sectorWidth*sectorCount;
                var trackWidth = this.track.width();
                var halfTrackWidth  =  Math.floor(trackWidth/2);
                var dragWidth = this.drag.width();
                var showSectorCount = Math.floor(trackWidth/sectorWidth);
                var leftMoveSector = Math.floor(showSectorCount/2);
                var rigthMoveSector =   sectorCount - (showSectorCount-leftMoveSector);
                var sliderratio = (areaWidth-trackWidth)/(trackWidth-dragWidth);
                if(trackWidth < areaWidth) {
                    this.viewAll = false;
                }
                else{
                    this.viewAll = true;
                }

                this.settings = {
                    'sectorWidth' : sectorWidth,
                    'halfSectorWidth' : halfSectorWidth,
                    'areaWidth' :  areaWidth ,
                    'trackWidth' : trackWidth,
                    'halfTrackWidth' : halfTrackWidth,
                    'leftMoveSector' : leftMoveSector,
                    'rigthMoveSector' : rigthMoveSector,
                    'sliderratio' : sliderratio
                };
         },
        
        move: function(sectorNum) {
            this.area.clearQueue();
            var pos;

            if(sectorNum>this.settings.leftMoveSector && sectorNum<this.settings.rigthMoveSector){
                pos = this.settings.sectorWidth * sectorNum + this.settings.halfSectorWidth - this.settings.halfTrackWidth;
            }
            else if(sectorNum<=this.settings.leftMoveSector){
                pos=0;
            }
            else if(sectorNum>=this.settings.rigthMoveSector){
                pos = this.settings.areaWidth -this.settings.trackWidth;
            }

            this.area.animate({scrollLeft:pos},250);
            this.drag.css('left', Math.round(pos/this.settings.sliderratio)+'px');
        },

        onResize: function() {
            if(this.instance==1)
            {
                this.countParams();

                if (this.viewAll) {
                    this.track.css('visibility', 'hidden');
                } else {
                    this.track.css('visibility', 'visible');
                }
                if(PhotoGallery.currentPos && PhotoGallery.currentPos !=='flash'){
                    this.move(parseInt(PhotoGallery.currentPos)+1);
                }
                else {
                    this.move(0);
                }

            }

        }
    };



    (function($) {

        $.fn.imSlider = function(options) {

                var element = this;

                if(options !== 'refreshImslider') {

                        var defaults = {
                                sliderScrollArea:                       '.sliderArea',
                                sliderScrollItems:                      'li',
                                sliderShadL:                            '.shd-l',
                                sliderShadR:                            '.shd-r',
                                sliderDrag:                     '.sliderdrag',
                                defaultItemOffsetWidth:          112
                        },
                        settings = $.extend({}, defaults, options);
                        element.data('settings',settings)
                }
                else {
                        settings = element.data('settings')
                }

                element.supportTouches_ = ( $.browser.webkit && navigator.userAgent.indexOf("Mobile") != -1 );

                element.events_ = {
                  "click": this.supportTouches_ ? "touchstart" : "click",
                  "down": this.supportTouches_ ? "touchstart" : "mousedown",
                  "move": this.supportTouches_ ? "touchmove" : "mousemove",
                  "up"  : this.supportTouches_ ? "touchend" : "mouseup"
                };

                element.each(function() {

                        var obj = $(this);
                        var objarea = $(settings.sliderScrollArea, obj);
                        var objareawidth = objarea.width();
                        var slideroffset;

                        var objcontainer = objarea.children();
                                objcontainer.width(elemwidth);
                        var slider = $(settings.sliderDrag, obj);
                        var dragtrack = $(settings.sliderDrag, obj).children();
                        var sliderwidth = slider.width();

                        var objisdrag = false;
                        var limitdrag = sliderwidth - dragtrack.width();
                        var halfdrag = dragtrack[0].offsetWidth/2;
                        var groupwidth = elemwidth - objareawidth;
                        var itemswidth = $(settings.sliderScrollItems, objarea).width();
                        var elemwidth = 0;
                        var sliderratio = 0;
                        $(settings.sliderScrollItems, objarea).each(function(){
                            var td =  $(this)[0];
                            var img = $('img',this)[0];
                            if(img.complete)
                            {
                                elemwidth = elemwidth + td.offsetWidth;
                            }
                            else
                            {
                                elemwidth = elemwidth + settings.defaultItemOffsetWidth;
                                img.onload = function(){
                                    elemwidth = elemwidth -settings.defaultItemOffsetWidth + td.offsetWidth;
                                    sliderratio = (elemwidth-objareawidth)/(sliderwidth-dragtrack.width());
                                    dragslider();
                                };
                            }

                        });
                        sliderratio = (elemwidth-objareawidth)/(sliderwidth-dragtrack.width());

                        if(objarea.find('.slider-drop').length) {
                                dragto();
                        }

                        $(settings.sliderDrag, obj).bind(element.events_.click, function(e){
                                objisdrag = true;
                                if(e.target != dragtrack[0]) {
                                        slideroffset = slider.offset().left;
                                        dragslider(e);
}
                                objisdrag = false;
                        });

                        dragtrack.bind(element.events_.down, function(event){
                                objisdrag = true;
                                slideroffset = slider.offset().left;
                                if(!element.supportTouches_ ) {
                                 $(document).bind(element.events_.move, dragslider);
                                }
                                return false;
                        });
                 
                        if(element.supportTouches_) {
                          $(document)[0].ontouchmove = function(event){dragslider(event)};
                        }

                        $(document).bind(element.events_.down, function(e){
                                if(objisdrag) {
                                        e.stopPropagation();
                                        e.preventDefault();
                                }
                        });
                        dragtrack.bind(element.events_.up, function(e){
                                if(objisdrag) {
                                        $(document).unbind(element.events_.move,dragslider);
                                        objisdrag = false;
                                }
                        });
                        $(document).bind(element.events_.up, function(){
                                $(document).unbind(element.events_.move,dragslider);
                                objisdrag = false;
                        });

                        function dragslider(event) {

                                    if(objisdrag) {
                                        if( event.touches && event.touches[0] ){
                                          var x = event.touches[0].pageX;
                                        } else {
                                                var x = event.pageX;
                                         };
                                        var pos = x - slideroffset - halfdrag;
                                        pos = (pos < 0) ? 0 : pos;
                                        pos = (pos > limitdrag) ? limitdrag : pos;
                                        dragtrack[0].style.left = pos + 'px';
                                        objarea[0].scrollLeft = Math.floor(pos*sliderratio);


                      disshd();
                                }
                        };
                        
                        function dragto() {
                                var $t = objarea.find('.slider-drop');
                                var pos = ($t[0].offsetLeft+33 - (objareawidth/2)) / sliderratio;

                                pos = (pos < 0) ? 0 : pos;
                                pos = (pos > limitdrag) ? limitdrag : pos;
                                dragtrack[0].style.left = pos + 'px';
                                objarea[0].scrollLeft = Math.floor(pos*sliderratio);
                                disshd();
                        };

                        function disshd() {
                                if(objarea[0].scrollLeft === groupwidth) {
                                        $(settings.sliderShadL,obj).removeClass('dis-shd');
                                        $(settings.sliderShadR,obj).addClass('dis-shd');
                                }
                                else if((objarea[0].scrollLeft === 0) && (elemwidth > objareawidth)) {
                                        $(settings.sliderShadL,obj).addClass('dis-shd');
                                        $(settings.sliderShadR,obj).removeClass('dis-shd');
                                }
                                else if(elemwidth <= objareawidth) {
                                  $(settings.sliderShadL,obj).hide();
                                                                          $(settings.sliderShadR,obj).hide();
                                                                                                          }
                                                                else {
                                                                          $(settings.sliderShadL,obj).removeClass('dis-shd');
                                                                          $(settings.sliderShadR,obj).removeClass('dis-shd');
                                                                                                                                                                                  }
                                                                                        };
                        
                }); // END: return this

                // returns the jQuery object to allow for chainability.  
                                 return element;
                                        };
 })(jQuery);


