/*
 *  jool.plug.scrollable based on jool 1.2
 *  http://joolapi.com/
 *
 *  This code (c) Copyright 2011 Giovanni Di Gregorio All Rights Reserved. 
 *  Released under licence MIT http://joolapi.com/license.txt
 *  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 *
 *  2011-05-11-04:21:18
*/

jool.plug = {
    scrollable: function(p) {
        return new j.plug.$scrollable(p);
    },
    $scrollable: function(p) {
        var direction = (p.direction == 'vertical') ? false: true;
        var duration = p.duration || 1;
        var ease = p.easing || 'linear';
        var fps = p.fps || 60;
        var scroller = p.scroller;
        var dragger = p.dragger;
        var content = p.content;
        var hcontent = p.hcontent;
        var hscroller = p.hscroller;
        var maxOpacity = p.maxOpacity || 100;
        var minOpacity = p.minOpacity || 100;
        var mobile,
        mover;
        this.action = 'plug';
        this.play = j.play;
        this.code = function() {
            if ($$(content)) {
                $$(dragger).onselectstart = function() {
                    return false;
                };
                $$(dragger).onmousedown = function() {
                    return false;
                };
                if (!direction) {
                    $$(dragger).style.marginTop = '0';
                    $$(content).style.marginTop = '0';
                } else {
                    $$(dragger).style.marginLeft = '0';
                    $$(content).style.marginLeft = '0';
                }
                var moveGallery = j.fx({
                    object: ['#' + content],
                    easing: ease,
                    duration: duration,
                    fps: fps
                });
                var moveDrag = j.fx({
                    object: ['#' + dragger],
                    duration: 1,
                    fps: 1
                });
                var spotDrag = j.fx({
                    object: ['#' + dragger],
                    duration: 200,
                    easing: 'quadOut',
                    next: j.fx({
                        duration: 200,
                        wait: 100,
                        easing: 'quadOut'
                    })
                });
                spotDrag.opacity = [minOpacity];
                spotDrag.play();
                if (j.sniff('iOS')) {
                    mobile = true;
                    mover = content;
                } else {
                    mobile = false;
                    mover = dragger;
                }
                function move(e) {
                    if (mobile) {
                        var mov = (!direction) ? -e.vpx: -e.hpx;
                    } else {
                        var mov = (!direction) ? e.vpx: e.hpx;
                    }
                    if (actTop + mov < 0) {
                        if (!direction) {
                            moveDrag.marginTop = [0];
                            moveGallery.marginTop = [0];
                        } else {
                            moveDrag.marginLeft = [0];
                            moveGallery.marginLeft = [0];
                        }
                    } else if (actTop + mov > difference) {
                        if (!direction) {
                            moveDrag.marginTop = [difference];
                            moveGallery.marginTop = [ - Math.round((difference) * delta)];
                        } else {
                            moveDrag.marginLeft = [difference];
                            moveGallery.marginLeft = [ - Math.round((difference) * delta)];
                        }
                    } else {
                        if (!direction) {
                            moveDrag.marginTop = [actTop + mov];
                            moveGallery.marginTop = [ - Math.round((actTop + mov) * delta)];
                        } else {
                            moveDrag.marginLeft = [actTop + mov];
                            moveGallery.marginLeft = [ - Math.round((actTop + mov) * delta)];
                        }
                    };
                    moveDrag.play();
                    moveGallery.play();
                }
                function start(e) {
                    spotDrag.opacity = [maxOpacity];
                    spotDrag.$.opacity = [maxOpacity];
                    spotDrag.play();
                    actTop = (!direction) ? $$(dragger).offsetTop: $$(dragger).offsetLeft;
                }
                function stop(e) {
                    spotDrag.opacity = [minOpacity];
                    spotDrag.$.opacity = [minOpacity];
                    spotDrag.play();
                    moveDrag.stop();
                }
                var scrollerHeight = (parseInt(hscroller, 10)) ? hscroller: $$(scroller).offsetHeight;
                var contentHeight = (parseInt(hcontent, 10)) ? hcontent: $$(content).offsetHeight;
                var delta = contentHeight / scrollerHeight;
                var draggerHeight = Math.round(scrollerHeight / delta);
                var difference = scrollerHeight - draggerHeight;
                var actTop;
                (!direction) ? $$(dragger).style.height = draggerHeight + 'px': $$(dragger).style.width = draggerHeight + 'px';
                if (scrollerHeight <= draggerHeight) {
                    $$(scroller).style.display = 'none';
                    $$(scroller).style.display = 'block';
                } else {
                    var draggable = j.event({
                        object: ['#' + mover],
                        event: 'drag',
                        touch: mobile,
                        preventDefault: true,
                        stopPropagation: true,
                        action: function(e) {
                            move(e);
                        },
                        actionstart: function(e) {
                            start(e);
                        },
                        actionstop: function(e) {
                            stop(e);
                        }
                    });
                    var selectable = j.event({
                        object: ['#' + content],
                        event: 'drag',
                        preventDefault: true,
                        stopPropagation: true,
                        action: function(e) {
                            move(e);
                        },
                        actionstart: function(e) {
                            start(e);
                        },
                        actionstop: function(e) {
                            stop(e);
                        }
                    });
                    function handle(deltaMouse) {
                        spotDrag.$.opacity = [minOpacity];
                        if (actTop + deltaMouse < 0) {
                            eventWheel.preventDefault = false;
                            spotDrag.opacity = [minOpacity];
                            if (!direction) {
                                moveDrag.marginTop = [0];
                                moveGallery.marginTop = [0];
                            } else {
                                moveDrag.marginLeft = [0];
                                moveGallery.marginLeft = [0];
                            }
                        } else if (actTop + deltaMouse > difference) {
                            eventWheel.preventDefault = false;
                            spotDrag.opacity = [minOpacity];
                            if (!direction) {
                                moveDrag.marginTop = [difference];
                                moveGallery.marginTop = [ - Math.round((difference) * delta)];
                            } else {
                                moveDrag.marginLeft = [difference];
                                moveGallery.marginLeft = [ - Math.round((difference) * delta)];
                            }
                        } else {
                            eventWheel.preventDefault = true;
                            spotDrag.opacity = [maxOpacity];
                            if (!direction) {
                                moveDrag.marginTop = [actTop + deltaMouse];
                                moveGallery.marginTop = [ - Math.round((actTop + deltaMouse) * delta)];
                            } else {
                                moveDrag.marginLeft = [actTop + deltaMouse];
                                moveGallery.marginLeft = [ - Math.round((actTop + deltaMouse) * delta)];
                            }
                        };
                        eventWheel.play();
                        spotDrag.play();
                        moveDrag.play();
                        moveGallery.play();
                    }
                }
                var eventWheel = j.event({
                    object: [content],
                    event: 'mousewheel',
                    stopPropagation: true,
                    action: function(e) {
                        actTop = (!direction) ? $$(dragger).offsetTop: $$(dragger).offsetLeft;
                        if (e.delta) handle( - e.delta);
                    }
                });
                eventWheel.play();
                draggable.play();
                selectable.play();
            } else {
                return true;
            }
        };
    }
};
