$.wwScrollableDock = {

    build : function( options ) {

        var  sd =   this;
        var $sd = $(this);

        sd.$listContainer = $( '.scrollable_dock_list_container', $(this) );
        sd.$list          = $( 'ul', sd.$listContainer );

        sd.$control       = $( '.scrollable_dock_control'      , $(this) );

        sd.$slider        = $( '.slider:first',    sd.$control );
        sd.$scrollbar     = $( '.scrollbar:first', sd.$control );

        sd.$items         = $( 'li.scrollable_dock_item', sd.$list );

        var $firstItem    = $( 'li.scrollable_dock_item:first', sd.$list);

        var itemBorderWidth  = parseInt( $firstItem.css( 'border-left-width' ) ) + parseInt( $firstItem.css( 'border-right-width'  ) );
        var itemBorderHeight = parseInt( $firstItem.css( 'border-top-width'  ) ) + parseInt( $firstItem.css( 'border-bottom-width' ) );

        sd.cfg = {

            // scrollable dock
            width                : $sd.width(),
            height               : $sd.height(),

            // listContainer
            listContainerWidth   : sd.$listContainer.width(),
            listContainerHeight  : sd.$listContainer.height(),
            listContainerCenterX : sd.$listContainer.width()  / 2,
            listContainerCenterY : sd.$listContainer.height() / 2,

            // list
            listWidth            : ( sd.$items.length - 1 ) * ( $firstItem.width() + itemBorderWidth + options.itemMarginRight ),

            // items
            numItems             : sd.$items.length,

            itemWidth            : $firstItem.width(),
            itemHeight           : $firstItem.height(),

            itemBorderWidth      : itemBorderWidth,
            itemBorderHeight     : itemBorderHeight,

            itemTotalWidth       : $firstItem.width()  + itemBorderWidth,
            itemTotalHeight      : $firstItem.height() + itemBorderHeight,

            itemMarginRight      : options.itemMarginRight,
            itemScaleMax         : options.itemScaleMax,

            startItem            : options.startItem - 1,

            // controls
            scrollAreaWidth      : sd.$scrollbar.width() - 2 * Math.floor( sd.$slider.width() / 2 ) - 1,

            animationTimeout     : options.animationTimeout != null ? options.animationTimeout : false

        }

        //sd.$list.width( sd.cfg.listWidth );

        var itemData = new Array();

        for ( var i = 0; i < sd.cfg.numItems; i++ ) {

            var itemInfo = new Object();

            itemInfo.centerX =  sd.cfg.listContainerCenterX + i * ( sd.cfg.itemTotalWidth + sd.cfg.itemMarginRight );
            itemInfo.centerY =  sd.cfg.listContainerCenterY;

            itemInfo.left = itemInfo.centerX - 0.5 * sd.cfg.itemTotalWidth;
            itemInfo.top  = itemInfo.centerY - 0.5 * sd.cfg.itemTotalHeight;

            itemInfo.img  = $('img.teaser_img', sd.$items[ i ]).get( 0 );

            itemData.push( itemInfo );

        }

        sd.itemData = itemData;

        $('.wait:first', $sd).css('display', 'none');


        var startPos = sd.cfg.startItem / (sd.$items.length - 1);

        $.wwScrollableDock.setSlider( sd, startPos);


        // event handling
        var drag = false;

	    sd.$slider.bind( 'mouseover', function () {
	        $(this).css( 'cursor', 'pointer' );
	        return false;
	    });

  	    sd.$slider.bind( 'mousedown', function ( e ) {
	        drag = true;
	        return false;
	    });


  	    sd.$slider.bind( 'mouseup', function ( e ) {
	        drag = false;
	        return false;
	    });


	    sd.$scrollbar.bind( 'mousedown', function ( e ) {

	        // mouseposition auf dem scrollbar ermitteln
	        var scrollPos = e.pageX - $(this).offset().left - Math.floor( sd.$slider.width() / 2 );
	        // var scrollPos = e.pageX - this.offsetLeft - Math.floor( sd.$slider.width() / 2 );
	        var sliderPos = scrollPos / sd.cfg.scrollAreaWidth;

	        $.wwScrollableDock.setSlider( sd, sliderPos );
	        return false;

	    });

	    sd.$slider.bind( 'mousemove', function ( e ) {

	        if ( drag ) {
	           $.wwScrollableDock.moveSlider( sd , e );
	        }
	        return false;

	    });

	    sd.$scrollbar.bind( 'mousemove', function ( e ) {

	        if ( drag ) {
	           $.wwScrollableDock.moveSlider( sd , e );
	        }
	        return false;

	    });



	},


	moveSlider : function ( sd, e ){

        var scrollPos = e.pageX - sd.$scrollbar.offset().left - Math.floor( sd.$slider.width() / 2 );
        var sliderPos = scrollPos / sd.cfg.scrollAreaWidth;

        $.wwScrollableDock.setSlider( sd, sliderPos );
	},

	setSlider : function( sd, pos ) {

  	    if ( pos < 0 ) pos = 0;
        if ( pos > 1 ) pos = 1;

        // sd.$slider.css( 'left', pos * sd.cfg.scrollAreaWidth );
        sd.$slider.get(0).style.left = pos * sd.cfg.scrollAreaWidth + 'px';

        if ( sd.cfg.animationTimeout ) {

            window.setTimeout( function (){

                $.wwScrollableDock.scroll ( sd, pos );

            }, sd.cfg.animationTimeout );

        }
        else{
            $.wwScrollableDock.scroll ( sd, pos );
        }

	},

	scroll : function( sd, sliderPos ) {

      var currentItem;
      var centerItem;
      var sliderOffset  = sliderPos * sd.cfg.listWidth;
      var minDistCenter = 1;

      var scale = 1;

      var i = 0;

      var visibleItemsL = new Array();
      var visibleItemsR = new Array();

      var scaleOffsetC = 0;
      var scaleOffsetL = 0;
      var scaleOffsetR = 0;

      var newW;
      var newH;

      for ( i = 0; i < sd.cfg.numItems; i++ ) {

          sd.$items[ i ].style.display = 'none';

          // je nach slider verschieben,
          sd.itemData[ i ].currLeft    = sd.itemData[ i ].left    - sliderOffset;

          sd.itemData[ i ].currCenterX = sd.itemData[ i ].centerX - sliderOffset;

          sd.itemData[ i ].currTop     = sd.itemData[ i ].top;
          sd.itemData[ i ].currCenterY = sd.itemData[ i ].centerY;

          sd.itemData[ i ].currDist = Math.abs ( sd.cfg.listContainerCenterX - sd.itemData[ i ].currCenterX ) / sd.cfg.listContainerCenterX;

          // item finden, welches am naechsten zum center ist
          if ( sd.itemData[ i ].currDist < minDistCenter) {

              minDistCenter = sd.itemData[ i ].currDist;
              centerItem = i;
          }

          // und weitere sichtbare items bestimmen
          if (    sd.itemData[ i ].currCenterX < sd.cfg.listContainerCenterX
               && sd.itemData[ i ].currCenterX + sd.cfg.itemTotalWidth / 2 >= 0 ) {

              visibleItemsL.push( i );
          }
          else if (    sd.itemData[ i ].currCenterX >  sd.cfg.listContainerCenterX
                    && sd.itemData[ i ].currLeft    <= sd.cfg.listContainerWidth ) {

              visibleItemsR.push( i );
          }

          sd.$items[ i ].style.left = sd.itemData[ i ].currLeft + 'px';
          sd.$items[ i ].style.top  = sd.itemData[ i ].currTop  + 'px';

      }


      // center item
      scale = 1 + ( 1 - sd.itemData[ centerItem ].currDist ) * ( sd.cfg.itemScaleMax - 1 );

      newW = sd.cfg.itemWidth  * scale;
      newH = sd.cfg.itemHeight * scale;

      scaleOffsetC = ( newW - sd.cfg.itemWidth ) / 2;

      sd.itemData[ centerItem ].currTop  -= ( newH - sd.cfg.itemHeight ) / 2;

      sd.$items[ centerItem ].style.width  = newW  + 'px';
      sd.$items[ centerItem ].style.height = newH  + 'px';

      sd.itemData[ centerItem ].img.style.width  = newW + 'px';
      sd.itemData[ centerItem ].img.style.height = newH + 'px';

      sd.itemData[ centerItem ].currLeft -= scaleOffsetC;

      sd.$items[ centerItem ].style.left = sd.itemData[ centerItem ].currLeft + 'px';
      sd.$items[ centerItem ].style.top  = sd.itemData[ centerItem ].currTop  + 'px';

      sd.$items[ centerItem ].style.display  = 'block';


      // items links davon
      for ( i = visibleItemsL.length - 1; i >= 0 ; i-- ){

          if ( visibleItemsL[ i ] == centerItem )
              continue;

          currItem = visibleItemsL[ i ];

          scale = 1 + ( 1 - sd.itemData[ currItem ].currDist ) * ( sd.cfg.itemScaleMax - 1 );

          newW = sd.cfg.itemWidth  * scale;
          newH = sd.cfg.itemHeight * scale;

          sd.$items[ currItem ].style.width  = newW  + 'px';
          sd.$items[ currItem ].style.height = newH  + 'px';

          sd.itemData[ currItem].img.style.width  = newW + 'px';
          sd.itemData[ currItem].img.style.height = newH + 'px';

          sd.itemData[ currItem ].currLeft -= ( scaleOffsetC + scaleOffsetL + ( newW - sd.cfg.itemWidth )  );

          sd.itemData[ currItem ].currTop  -= ( newH - sd.cfg.itemHeight ) / 2;

          sd.$items[ currItem ].style.left = sd.itemData[ currItem ].currLeft + 'px';
          sd.$items[ currItem ].style.top  = sd.itemData[ currItem ].currTop  + 'px';

          scaleOffsetL += newW - sd.cfg.itemWidth;

          sd.$items[ currItem ].style.display  = 'block';

      }

      // items rechts davon
      for ( i = 0; i < visibleItemsR.length; i++ ){

          if ( visibleItemsR[ i ] == centerItem )
              continue;

          currItem = visibleItemsR[ i ];

          scale = 1 + ( 1 - sd.itemData[ currItem ] .currDist ) * ( sd.cfg.itemScaleMax - 1 );

          newW = sd.cfg.itemWidth  * scale;
          newH = sd.cfg.itemHeight * scale;

          sd.$items[ currItem ].style.width  = newW  + 'px';
          sd.$items[ currItem ].style.height = newH  + 'px';

          sd.itemData[ currItem].img.style.width  = newW + 'px';
          sd.itemData[ currItem].img.style.height = newH + 'px';

          sd.itemData[ currItem ].currLeft += scaleOffsetC + scaleOffsetR ;
          sd.itemData[ currItem ].currTop  -= ( newH - sd.cfg.itemHeight ) / 2;

          sd.$items[ currItem ].style.left = sd.itemData[ currItem ].currLeft + 'px';
          sd.$items[ currItem ].style.top  = sd.itemData[ currItem ].currTop  + 'px';

          scaleOffsetR += newW - sd.cfg.itemWidth;

          sd.$items[ currItem ].style.display  = 'block';

      }


	}

};

$.fn.wwScrollableDock = $.wwScrollableDock.build;
