			
		// on init
		$(function() {	
		
			// init scrollboxes
			$('[scrollbox]')
				.each(
					function (){
						
						
						// scrollbox object --------------------------------------------------
						var that = this,
							scrollbox = {									// object per scrollbox
								jqObj	: $(that),							// save "this" scrollbox
								id 		: $(that).attr('scrollbox'),		// the id
								animdiv : null,								// set later
								height 	: $(that).attr('height'),
								
								// Physix ------------------------------------------------------------
								physix 	: {
									pos			: 0,	// px (float, real value)
									offset		: 0,	// px (int, css-value)
									speed 		: 0,	// px/s
									maxspeed 	: 200, 	// px/s
									accel 		: 0,   	// px/sē 
									friction	: 200,	// px/sē (allways against speed)
									lastupdate	: 0,	// initial value
									working		: false, 
									
									update: function () {
										var that = this;
										if (that.lastupdate && (that.accel!=0 || that.speed!=0)){
											
											// calculate physix
											var timediv = (new Date().getTime() - that.lastupdate) / 1000; 					// timediv in s
											that.speed 	+= that.accel  * timediv;											// speed
											var frictionspeed = ((that.speed < 0)? that.friction : - that.friction ) * timediv;
											that.speed = ( Math.abs(frictionspeed) > Math.abs(that.speed) )? 0 : that.speed + frictionspeed;	// if the frictional caused part of the speed (decrease) is greater than the the total speed -> its stopped, not reversed!
											that.speed = Math.max( Math.min( that.speed, that.maxspeed), -that.maxspeed); 	// speed limit in both directions 
											that.pos 	+= that.speed * timediv;											// position
											
											if (that.pos > that.posmax ) { that.pos = that.posmax; that.speed = 0; }			// Position limit
											if (that.pos < that.posmin ) { that.pos = that.posmin; that.speed = 0; }
											
											if (Math.floor(that.pos) != that.offset ){	// update DOM only if current DOM value differs from position			
												that.offset = Math.floor(that.pos)
												scrollbox.animdiv.css({ "margin-top" : that.offset });
											}
										}
										
										// Quiet down
										if (Math.abs(that.speed) < 1 ) that.speed = 0;	
										if (Math.abs(that.accel) < 1 ) that.accel = 0;	
										
										// call again after timeout ---------------
										if (that.accel!=0 || that.speed!=0){
											that.working = true;
											that.lastupdate = new Date().getTime();
											window.setTimeout( function(){ that.update(); }, 20);
										}
										else {
											that.working = false;
											that.lastupdate = undefined;
										}
										// console.log(that.speed +  " - " + that.accel)
									},
									// one time calculations
									init: function () {
										this.posmin = (scrollbox.animdiv.height() > scrollbox.height)? scrollbox.height - scrollbox.animdiv.height() : 0 ;
										this.posmax = 0;
										
										
									}
								},
								// init scrollbox
								init : function () {	
									scrollbox.jqObj
										.css({ 										// limit height of scrollbox
											overflow: 'hidden',
											height: scrollbox.height
										})
										.wrapInner("<div>");					// insert additional "inner" div around content
									scrollbox.animdiv = scrollbox.jqObj.find('>div');	// store a reference to the new "inner" animated layer
									scrollbox.physix.init();						// init physics
									
									// hide scrollers for this box if not needed 
									if (scrollbox.animdiv.height() < scrollbox.height){
										$('[scroll="' + scrollbox.id + '"][accel]').find('img').css({ visibility: 'hidden' });
									};
									
									// mousewheel for scroller
									scrollbox.jqObj.mousewheel(
										function ( event, delta) {
											scrollbox.physix.pos += delta*26;
											if (scrollbox.physix.pos > scrollbox.physix.posmax ) { scrollbox.physix.pos = scrollbox.physix.posmax; scrollbox.physix.speed = 0; }			// Position limit
											if (scrollbox.physix.pos < scrollbox.physix.posmin ) { scrollbox.physix.pos = scrollbox.physix.posmin; scrollbox.physix.speed = 0; }
											scrollbox.physix.offset = Math.floor(scrollbox.physix.pos)
											scrollbox.animdiv.css({ "margin-top" : scrollbox.physix.offset });
											return false;
										}
									);

									
								}
							}
						
						scrollbox.init();
						
						// aktivate scroll buttons for "this" scrollbox
						$('[scroll="' + scrollbox.id + '"][accel]')
							.css({ cursor : 'pointer' })
							.hover(
								function(){
									// console.log($(this).attr('accel'));
									/* scrollbox.physix.accel = + $(this).attr('accel'); */
									scrollbox.physix.accel = ($(this).attr('accel') >= 0)? 
										+ $(this).attr('accel') + scrollbox.physix.friction : 
										+ $(this).attr('accel') - scrollbox.physix.friction ;
									if (!scrollbox.physix.working) scrollbox.physix.update();
								},
								function(){
									scrollbox.physix.accel = 0;
								}
							)
						
					}
				);
		
		});
