var sandstorm = sandstorm ||
{}

// swipe event should be listened for here as well.

sandstorm.PipeCircular = function(target,incrementor,useWebkitTransitions,ulSelector,leftArrow,rightArrow)
{
    this.MIN_TRACKING_FOR_DRAG = 15;
    this.PERCENT_CHANGE_THRESHOLD = 20;
    this.element = target;
    this._currentPage = 0;
    this.elementWidth = null;
    this.rebuiltList = null;
    this.mouseStartX = null;
    this.lastPlacedTouch = null;
    this.ulInTransition = false;
    this.useWebkitTransitions = useWebkitTransitions == true ? true : false;
    this.ulSelector = ulSelector ? ulSelector : '> ul';
    this.ul = this.element.find(this.ulSelector);
    this.originalLength = this.ul.find("li").length;
    this.ulStartX = 0;
    this._isDragging = false;
    this.pageWidth = $(window).width();
    this.rebuild();
    this.restyle();
    this.totalPages = this.rebuiltList.length;
    this.resortForPage(this._currentPage);
	this.incrementor = incrementor == null ? 1 : incrementor;
	
	
    this.rightArrow = leftArrow ? leftArrow : target.find(".right-arrow.arrow-button");
    this.leftArrow = rightArrow ? rightArrow : target.find(".left-arrow.arrow-button");
	
    var scope = this;
    this.rightArrow.click(function()
	{
        scope.previous();
    });
    
    this.leftArrow.click(function()
	{
        scope.next();
    });
    if(!this.useWebkitTransitions){
    	$(this.ulSelector).css('position','absolute');
    }else{
    	this.ul[0].addEventListener('touchstart', this, false);
		this.ul[0].addEventListener('touchmove', this, false);
		this.ul[0].addEventListener('touchend', this, false);
    }
}

sandstorm.PipeCircular.prototype.next = function()
{
	var slidesToPaginate = this.incrementor;
    var stageWidth = this.pageWidth;
    var itemsInView = Math.round(stageWidth / this.elementWidth);
    var startx = -itemsInView * this.elementWidth;
    var newxPos = startx - ((this._currentPage + slidesToPaginate) * this.elementWidth);
    var propertys = {};
    propertys.time = 500;
    propertys.xPos = newxPos;
    this.animateTo(this.ul, propertys);
    this.setCurrentPage(this._currentPage + slidesToPaginate);
}

sandstorm.PipeCircular.prototype.previous = function()
{
    var slidesToPaginate = this.incrementor;
    var stageWidth = this.pageWidth;
    var itemsInView = Math.round(stageWidth / this.elementWidth);
    var startx = -itemsInView * this.elementWidth;
    var newxPos = startx - ((this._currentPage - slidesToPaginate) * this.elementWidth);
    var propertys = {};
    propertys.time = 500;
    propertys.xPos = newxPos;
    this.animateTo(this.ul, propertys);
    this.setCurrentPage(this._currentPage - slidesToPaginate);
}

//this method is used to move the li's around.  if you are moving the ul, you have to call this afterwards
sandstorm.PipeCircular.prototype.setCurrentPage = function(value)

{
    var diff = this._currentPage - value;
	this._currentPage = value;
    var absDiff = Math.abs(diff);
    var i = 0;
    if (diff > 0) 
    {
        while (i < absDiff) 
        {
			this.unshiftLi();
            i++
        }
    }
    else 
    {
        while (i < absDiff) 
        {
            this.popLi();
            i++
        }
    }
    
    
    var pageDot;
    if (this._currentPage > 0) 
    {
        pageDot = this._currentPage % this.originalLength;
    }
    else 
    {
        pageDot = Math.abs(this._currentPage);
        pageDot = (pageDot % this.originalLength) + 1;
        pageDot = this.originalLength - pageDot;
    }
    this.changePageDots(pageDot);
}

sandstorm.PipeCircular.prototype.changePageDots = function(page)
{
    var dotsList = this.element.find(".paging-dots ul li");
    if (dotsList.length == 0) return;
    dotsList.removeClass("selected");
    dotsList.eq(page).addClass("selected");
}

//take from left put on right
sandstorm.PipeCircular.prototype.popLi = function()
{
	var leftItem = this.getLeftItem();
    var rightItem = this.getRightItem();
    var propertys = {};
    propertys.time = 0;
    propertys.xPos = this.getXVal(rightItem) + this.elementWidth;
    this.animateTo(leftItem, propertys);
}

//take from right put on left
sandstorm.PipeCircular.prototype.unshiftLi = function()
{
    var leftItem = this.getLeftItem();
    var rightItem = this.getRightItem();
    var propertys = {};
    propertys.time = 0;
    propertys.xPos = this.getXVal(leftItem) - this.elementWidth;
    this.animateTo(rightItem, propertys);
}

sandstorm.PipeCircular.prototype.getLeftItem = function()
{
    var leftItem = null;
    var leftxVal = null;
    for (var i = this.rebuiltList.length - 1; i >= 0; i--) 
    {
        var listItem = this.rebuiltList.eq(i);
        var xVal = this.getXVal(listItem);
        if (!leftItem) 
        {
            leftItem = listItem;
            leftxVal = xVal;
            continue;
        }
        if (xVal < leftxVal) 
        {
            leftItem = listItem;
            leftxVal = xVal;
        }
    }
    return leftItem;
}

sandstorm.PipeCircular.prototype.getRightItem = function()
{
    var rightItem = null;
    var rightxVal = null;
    for (var i = this.rebuiltList.length - 1; i >= 0; i--) 
    {
        var listItem = this.rebuiltList.eq(i);
        var xVal = this.getXVal(listItem);
        if (!rightItem) 
        {
            rightItem = listItem;
            rightxVal = xVal;
            continue;
        }
        if (xVal > rightxVal) 
        {
            rightItem = listItem;
            rightxVal = xVal;
        }
    }
    return rightItem;
}

sandstorm.PipeCircular.prototype.getXVal = function(obj)
{
    var leftPos = obj[0].style.left.replace('px', '');
	
    if (this.useWebkitTransitions) 
    {
        var xPropStr = obj.css("-webkit-transform");
	    var tempArr = xPropStr.split(",");
	    var xTransform = tempArr[4];
	    xTransform = xTransform ? xTransform : 0;
		leftPos = xTransform;
    }
    return parseInt(leftPos, 10);
}

sandstorm.PipeCircular.prototype.rebuild = function()
{
    var ul = this.element.find(this.ulSelector);
    var list = this.element.find(this.ulSelector+" li");
    this.elementWidth = list.eq(0).outerWidth(true);
    var stageWidth = $(window).width();
    var itemsInView = Math.round(stageWidth / this.elementWidth);
    var totalItemsToDisplay = itemsInView * 3;
    
    //check if you need to add items 
    var i = 0;
    var listLength = list.length;
    while (listLength + i < totalItemsToDisplay) 
    {
        ul.append(list.eq(i % listLength).clone());
        i++;
    }
    this.rebuiltList = this.element.find(this.ulSelector+" li");
    var propertys = {};
    propertys.time = 0;
    propertys.xPos = -itemsInView * this.elementWidth;
    this.animateTo(this.element.find(this.ulSelector), propertys);
}

sandstorm.PipeCircular.prototype.restyle = function(page)
{
    this.rebuiltList.css({
        "position": "absolute",
        "float": "none"
    })
}

sandstorm.PipeCircular.prototype.resortForPage = function(page)
{
    var scope = this;
    this.rebuiltList.each(function(index)
    {
        var propertys = {};
        propertys.time = 0;
        propertys.xPos = index * scope.elementWidth;
        scope.animateTo($(this), propertys);
    })
}



sandstorm.PipeCircular.prototype.handleEvent = function(e)
{
    switch (e.type)
    {
        case "touchstart":
            this.onTouchStart(e);
            break;
            
        case "touchmove":
            this.onTouchMove(e);
            break;
            
        case "touchend":
            this.onTouchEnd(e);
            break;
    }
}

sandstorm.PipeCircular.prototype.onTouchStart = function(e)
{
    this.mouseStartX = e.touches[0].clientX;
    this.ulStartX = this.leftPos();
    this.startX = e.touches[0].clientX;
    this.lastPlacedTouch = e.touches[0].clientX;
}


sandstorm.PipeCircular.prototype.onTouchMove = function(e)
{

    this.lastPlacedTouch = e.touches[0].clientX;
    var newOffsetX = this.startX - e.touches[0].clientX;
    
    if (this.isDragging(newOffsetX)) 
    {
        var nextPosition = this.ulStartX - newOffsetX;
        var nextPage = (nextPosition * -1 / this.elementWidth);
        nextPage = (this.lastPlacedTouch > this.startX) ? Math.ceil(nextPage) : Math.floor(nextPage);
        var propertys = {};
        propertys.time = 0;
        propertys.xPos = nextPosition;
        this.animateTo(this.ul, propertys);
    }
    
    var changeX = this.startX - e.touches[0].clientX;
    if (changeX > this.MIN_TRACKING_FOR_DRAG) 
    {
        document.body.addEventListener('touchmove', this.disableNativeScrolling);
    }
}

sandstorm.PipeCircular.prototype.onTouchEnd = function(e)
{
    document.body.removeEventListener('touchmove', this.disableNativeScrolling);
    this._isDragging = false;
    
    //have to recalculate the ulleft position because if you click when its in the middle of a transition your numbers will be off.  
    var stageWidth = this.pageWidth;
    var itemsInView = Math.round(stageWidth / this.elementWidth);
    var startx = -itemsInView * this.elementWidth;
    var ulLeft = startx - this._currentPage * this.elementWidth;
    
    
    var leftPos = this.leftPos();
    leftPos = leftPos || 0;
    var dragChange = this.startX - this.lastPlacedTouch;
    if (leftPos == 0 && dragChange <= 0) return;
    var dragPercent = Math.abs(dragChange / this.elementWidth * 100);
    
    
    //put back to its start spot, didn't move it enough
    if (dragPercent <= this.PERCENT_CHANGE_THRESHOLD) 
    {
        var propertys = {};
        propertys.time = 500;
        propertys.xPos = ulLeft;
        this.animateTo(this.ul, propertys);
        return;
    }
    
    var pageChange = Math.abs(Math.round(dragChange / this.elementWidth));
    
    //if the threshold of a change page has been met, but it would land back where it previously was...we give it a little help and move it +/- 1
    if (pageChange == 0) 
    {
        pageChange = 1;
    }
    
    if (dragChange > 0) 
    {
        var newxPos = ulLeft - this.elementWidth * pageChange;
    }
    else 
    {
        var newxPos = ulLeft + this.elementWidth * pageChange;
        pageChange = -pageChange;
    }
    
    this.setCurrentPage(this._currentPage + pageChange);
    var propertys = {};
    propertys.time = 500;
    propertys.xPos = newxPos;
    this.animateTo(this.ul, propertys);
}

sandstorm.PipeCircular.prototype.isDragging = function(touchX)
{
    if (this._isDragging) return this._isDragging;
    if (touchX) 
    {
        if (Math.abs(touchX) > this.MIN_TRACKING_FOR_DRAG) 
        {
            this._isDragging = true;
            return this._isDragging;
        }
    }
    return false;
}

sandstorm.PipeCircular.prototype.disableNativeScrolling = function(e)
{
    e.preventDefault();
}




sandstorm.PipeCircular.prototype.leftPos = function()
{
    var xPropStr = this.ul.css("-webkit-transform");
    var tempArr = xPropStr.split(",");
    var xTransform = tempArr[4];
    xTransform = xTransform ? xTransform : 0;
    var leftPos = this.ul[0].style.left.replace('px', '');
	//console.log(leftPos);
    if (this.useWebkitTransitions) leftPos = xTransform;
	//console.log(sandstorm.application.currentDevice.platform);
    return parseInt(leftPos, 10);
}




//pass in jquery object
sandstorm.PipeCircular.prototype.animateTo = function(dispObject, propertys)
{
    if (!propertys) 
    {
        propertys = {};
        propertys.time = 0;
        propertys.callback = null;
        propertys.xPos = 0;
    }
    if (!propertys.time) 
    {
        propertys.time = 0;
    }
    if (!this.useWebkitTransitions) 
    {
        if (propertys.time == 0) 
        
        {
            dispObject.css({
                'left': propertys.xPos + "px"
            });
            if (propertys.callback) 
            {
                propertys.callback();
            }
        }
        else 
        {
            dispObject.animate({
                left: propertys.xPos
            }, propertys.time, function()
            {
                if (propertys.callback) propertys.callback();
            });
        }
    }
    else 
    {
        dispObject[0].style.webkitTransition = '-webkit-transform ' + propertys.time + 'ms ';
        dispObject[0].style.webkitTransform = 'translate3d(' + propertys.xPos + 'px, 0, 0)';
        if (propertys.callback) 
        {
            dispObject[0].addEventListener("webkitTransitionEnd", function()
            {
                return function()
                {
                    propertys.callback();
                    dispObject[0].removeEventListener("webkitTransitionEnd", arguments.callee);
                }
            }())
        }
    }
}



















