/* konaRoll.js
 *
 *
 */

var konaRoll = function( selector, userOptions ) {
    
    if ( !jQuery ) {
        throw('jQuery is undefined.');
    }
    
    var _this;
    
    var _container, _outerContainer, _innerContainer, _panel, _panelSize, _panelWidth, _panelHeight, _movingDistance, _rollInterval;
    
    var _axis, _rollDirection, _speed, _scroll = 0;
    
    var _distanceMode, _scrollMode;
    
    var _curPanel, _viewNum;
    
    var _clickMoving = 0, _clickStatus = 0;
    
    var options;
    
    
    
    var defOptions = {
        
        direction: 'left',
        
        auto: 1,
        
        step: 1,
        
        cycle: 1,
        
	easing: 'swing',
        
	panel: 'li',
        
        curPanel: 0,
	
	minPanelSize: 0,
        
        viewNum: null,
        
	mouseEnterStop: 1,
	
	delay: 5000,
	
	speed: 1000,
	
	px: 0,
	
	row: 1,
        
        controller:{
            
            prevId: null,
            
            nextId: null,
            
            numberId: null,
	    
	    easing: null,
	    
	    speed: null,
	    
	    delay: null,
	    
	    step: null,
	    
	    px: null,
	    
	    continuous: 1,
	    
            directionChange: 0
        }
        
    }
    
    function init() {
        
        _container = $( selector );
        
        options = $.extend( true, {}, defOptions, userOptions );
        
        initDirection();
        
        initBuildDom();
        
	if ( _panelSize < _viewNum ) {
	    return;
	}
	
        if ( _axis ) {
            
	    _movingDistance = _panelHeight;
	    
            _scrollMode = 'scrollTop';
            
            _distanceMode = 'height';
            
        } else {
            
	    _movingDistance = _panelWidth;
	    
            _scrollMode = 'scrollLeft';
            
            _distanceMode = 'width';
            
        }
	
	options.controller.easing = options.controller.easing ? options.controller.easing : options.easing;
	
	options.controller.speed = typeof options.controller.speed == 'number' ? options.controller.speed : options.speed;
	
	options.controller.delay = typeof options.controller.delay == 'number' ? options.controller.delay : options.delay;
	
	options.controller.step = typeof options.controller.step == 'number' ? options.controller.step : options.step;
	
	options.controller.px = typeof options.controller.px == 'number' ? options.controller.px : options.px;
	
        
        _outerContainer.scrollLeft(0).scrollTop(0);
        
        speed( options.speed );
	
	
	autoRoll();
	
	mouseEnterStop();
	
	if ( options.controller.prevId ) {
	    
	    $( options.controller.prevId ).bind( 'mousedown', function(){
		
		mouseController(0);
		
	    }).mouseup(mouseUp).mouseout(mouseUp);
	    
	}
	
	if ( options.controller.nextId ) {
	    
	    $( options.controller.nextId ).bind( 'mousedown', function(){
		
		mouseController(1);
		
	    }).mouseup(mouseUp).mouseout(mouseUp);
	    
	}
	
        
    }
    
    function initDirection() {
        
        if ( options.direction == 'up' ){
	    
	    _axis = 1;
	    
	    _rollDirection = 0;
	    
	} else if( options.direction == 'right' ) {
	    
	    _axis = 0;
	    
	    _rollDirection = 1;
	    
	} else if ( options.direction == 'down') {
	    
	    _axis = 1;
	    
	    _rollDirection = 1;
	    
	} else {
	    
	    _axis = 0;
	    
	    _rollDirection = 0;
	    
	}
        
    }
    
    function initBuildDom() {
        
        var rows, cols;
        
        _panel = _container.find(options.panel).eq(0).nextAll().andSelf();
        
        _panelSize = _panel.size();
        
        _panelWidth = _panel.outerWidth(1);
        
        _panelHeight = _panel.outerHeight(1);
	
	
	_viewNum = options.minPanelSize;
	
	if ( _panelSize < _viewNum ) {
	    return;
	}
	
	
        _container.wrapInner('<div></div>').wrapInner('<div></div>');
        
        _outerContainer = _container.children('div');
        
        _innerContainer = _outerContainer.children('div');
	
	
	
        
        _outerContainer.css({
            
            width: _container.width(),
            
            height: _container.height(),
	    
	    overflow: 'hidden'
            
        });
        
        rows = options.row;
	
	cols = Math.ceil( _panelSize / rows );
        
        
        
        if ( options.cycle ) {
            
            _innerContainer.css({
                
                width: _axis ? _panelWidth * rows : _panelWidth * cols * 3,
                
                height: _axis ? _panelHeight * cols * 3 : _panelHeight * rows
                
            });
            
            _innerContainer.children().clone().appendTo(_innerContainer).clone().appendTo(_innerContainer);
            
        } else {
            
            _innerContainer.css({
                
                width: _axis ? _panelWidth * rows : _panelWidth * cols,
                
                height: _axis ? _panelHeight * cols : _panelHeight * rows
                
            });
        }
    }
    
    function autoRoll() {
	
	if ( options.auto && options.cycle ) {
            
            _rollInterval = setInterval(function() {
                
                roll();
                
            }, options.delay + _speed );
            
        }
	
    }
    
    function speed( t ) {
        
        if ( arguments.length == 0 ) {
            
            return _speed;
        }
        
        _speed = t;
        
        return this;
    }
    
    function countScroll( direction, step, px ) {
	
	var increScroll = _movingDistance * step;
	
	if ( typeof px == 'number' && px != 0 ) {
	    
	    increScroll = px;
	    
	}
	
	if ( direction == 0 ) {
	    
	    _scroll += increScroll;
	    
	} else {
	    
	    _scroll -= increScroll;
	    
	}
	
	if( options.cycle ) {
	    
	    if ( _scroll > _innerContainer[_distanceMode]() - _outerContainer[_distanceMode]() ) {
		
		_outerContainer[_scrollMode]( _outerContainer[_scrollMode]() - _innerContainer[_distanceMode]() / 3 );
		
		_scroll = _scroll - _innerContainer[_distanceMode]() / 3;
		
	    } else if ( _scroll < 0 ) {
		
		_outerContainer[_scrollMode]( _outerContainer[_scrollMode]() + _innerContainer[_distanceMode]() / 3 );
		
		_scroll = _scroll + _innerContainer[_distanceMode]() / 3;
		
	    }
	    
	} else {
	    
	    if ( _scroll < 0 ) {
		
		_scroll = 0;
		
	    } else if ( _scroll > ( _panelLength - _totalViewPanel ) * _panelWidth ) {
		
		_scroll = ( _panelLength - _totalViewPanel ) * _panelWidth;
	    }
	    
	}
	
    }
    
    function mouseEnterStop() {
	
	if ( options.mouseEnterStop ) {
	    
	    _outerContainer.mouseover(function(){
		
		clearInterval( _rollInterval );
		
	    }).mouseout(function(){
		
		autoRoll();
		
	    })
	    
	}
	
    }
    
    function mouseController( direction ) {
	
	
	if ( _clickMoving == 1 ) {
	    return;
	}
	
	clearInterval( _rollInterval );
	
	_outerContainer.stop();
	
	_clickMoving = 1;
	
	_clickStatus = 1;
	
	roll( direction, options.controller.step, options.controller.speed, options.controller.easing , mouseCallback, options.controller.px );
	
	if ( options.controller.continuous ) {
	    
	    _rollInterval = setInterval(function(){
		
		if ( _clickStatus == 0 ) {
		    
		    clearInterval( _rollInterval );
		    
		    autoRoll();
		    
		    return;
		}
		
		roll( direction, options.controller.step, options.controller.speed, options.controller.easing , mouseCallback, options.controller.px );
		
	    }, options.controller.speed + options.controller.delay );
	    
	}
	
	if ( options.controller.directionChange ) {
	    
	    _rollDirection = direction;
	    
	}
	
    }
    
    function mouseUp() {
	
	_clickStatus = 0;
	
    }

    function mouseCallback() {
	
	if ( _clickStatus == 0 || !options.controller.continuous ) {
	    
	    _clickMoving = 0;
	    
	    clearInterval( _rollInterval );
	    
	    autoRoll();
	    
	}
	
    }
    
    function noop() {
	
    }
    
    function roll( d, s, t, e, f, p ) {
        
        var direction, step, time, easing, px, func, params = {};
        
        if ( typeof d == 'object' ) {
            
            direction = obj.direction != undefined ? obj.direction : _rollDirection;
            
            step = obj.step != undefined ? obj.step : options.step;
            
            time = obj.time != undefined ? obj.time : _speed;
            
            px = obj.px != undefined ? obj.px : options.px;
            
            easing = obj.easing ? obj.easing : options.easing;
            
        } else {
            
            direction = typeof d == 'number' ? d : _rollDirection;
            
            step = s ? s : options.step;
            
            time = t ? t : _speed;
            
            px = p ? p : options.px;
            
            easing = e ? e : options.easing;
	    
	    func = f ? f : noop;
            
        }
        
	countScroll( direction, step, px );
	
        params[_scrollMode] = _scroll;
	
	    _outerContainer.stop().animate( params, time, easing, func );
	
    }
    
   init();
    
};



