import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
/**
 *
 * @author AlexeyW
 */
public class ScrollBar {
    
    private boolean vScroll, stopping, kScroll;
    private int pScroll, lY, wX, wY, wWidth, wHeight, value, mValue, sHeight, dir, bx, scrolling;
    private int[] scroll;
    private float sAspect, sSpeed, sTime, time, dist, dist_prev, mAspect;
    private long lTime, sTimePrev;
    
    /*
     * Конструктор класса, инициализирует и принимает, wX и wY и wWidth и wHeight - положение скролла на экране, и его ширина с высотой, mValue - максимальное value скролла,
     * extent - диапазон (мат. высота) скролла
     */
    public ScrollBar(int wX, int wY, int wWidth, int wHeight, int mValue, int extent, boolean kScroll) {
        this.wX = wX;
        this.wY = wY;
        this.wWidth = wWidth;
        this.wHeight = wHeight;
        this.mValue = mValue;
        this.kScroll = kScroll;
        
        sHeight = (int)((float)wHeight*((float)wHeight/(float)extent));
        sAspect = (float)(wHeight-sHeight)/(float)mValue;
        
        scroll = new int[2*sHeight];
        for(int i=0; i<scroll.length; i++) scroll[i] = 0x3fffffff;
        
        mAspect = 5;
        
        vScroll = true;
    }
    
    public void setMovingAspect(float f) {
        mAspect = f;
    }
    
    /*
     * Переводит скролл в начальное положение (на 0)
     */
    public void init() {
        value = 0;
        pScroll = 0;
    }
    
    /*
     * Устанавливает видимость скролла, false - невидим
     */
    public void setVisibleScroll(boolean flag) {
        vScroll = flag;
    }
    
    /*
     * Возвращает value скролла
     */
    public int getValue() {
        return value;
    }
    
    /*
     * Устанавливает value скролла
     */
    public void setValue(int value) {
        if(value < 0) value = 0;
        if(value > mValue) value = mValue;
        this.value = value;
        pScroll = (int)((float)value*sAspect);
    }
    
    public boolean setScrollingValue(int value) {
        boolean flag = false;
        if(value < 0) {
            value = 0;
            flag = true;
        }
        if(value > mValue) {
            value = mValue;
            flag = true;
        }
        this.value = value;
        pScroll = (int)((float)value*sAspect);
        return flag;
    }
    
    /*
     * Цикличная функция, принимает fps_time - 1/fps, проверяет нажатие кнопок и нажатия на экран, нажатия на экран типа presssed, released, dragged
     */
    public void pCheck(float fps_time, int dKey, int pX, int pY, int rX, int rY, int dX, int dY) {
        if(scrolling == 0) {
            if(Wand.region(pX, pY, wX, wY, wWidth, wHeight)) {
                lY = pY;
                sSpeed = sTime = bx = dir = 0;
                stopping = false;
                lTime = System.currentTimeMillis();
            }
            if(Wand.region(dX, dY, wX, wY, wWidth, wHeight)) {
                pScroll+=lY-dY;
                if(pScroll < 0) pScroll = 0;
                if(pScroll > wHeight-sHeight) pScroll = wHeight-sHeight;
                value = (int)((float)pScroll/sAspect);

                float distance = (float)Math.sqrt((dY-lY)*(dY-lY));
                float time = (float)(System.currentTimeMillis()-lTime)/1000f;
                lTime = System.currentTimeMillis();
                if(time != 0) sSpeed = distance/time;
                if(lY < dY) dir = 1;
                if(lY > dY) dir = 2;

                lY = dY;
            }
            if(Wand.region(rX, rY, wX, wY, wWidth, wHeight) || stopping) {
                if(sSpeed != 0) {
                    int x = (int)(sSpeed*sTime-1000f*(sTime*sTime)/2f);
                    if(x >= bx) {
                        sTime += fps_time;
                        if(dir == 1) pScroll -= (int)(x-bx);
                        if(dir == 2) pScroll += (int)(x-bx);
                        if(pScroll < 0) pScroll = 0;
                        if(pScroll > wHeight-sHeight) pScroll = wHeight-sHeight;
                        value = (int)((float)pScroll/sAspect);
                        bx = x;
                        stopping = true;
                    } else {
                        stopping = false;
                    }
                }
            }
            if(kScroll && scrolling == 0) {
                if(dKey == -1 || dKey == Canvas.KEY_NUM2 || dKey == 116) {
                    scrolling = 1;
                    sTimePrev = System.currentTimeMillis();
                }
                if(dKey == -2 || dKey == Canvas.KEY_NUM8 || dKey == 98) {
                    scrolling = 2;
                    sTimePrev = System.currentTimeMillis();
                }
            }
        } else {
            if(scrolling != 0) {
                time = (System.currentTimeMillis()-sTimePrev)/1000f;
                dist = (mAspect*time-12f*(time*time)/2)*100;
                if(scrolling == 1) {
                    if(setScrollingValue(getValue()-(int)(dist-dist_prev)) || dist < dist_prev) {
                        scrolling = 0;
                    }
                }
                if(scrolling == 2) {
                    if(setScrollingValue(getValue()+(int)(dist-dist_prev)) || dist < dist_prev) {
                        scrolling = 0;
                    }
                }
                if(scrolling != 0) {
                    dist_prev = dist;
                } else {
                    dist_prev = 0;
                }
            }
        }
    }
    
    /*
     * Цикличная функция, принимает класс Graphics и отображает скролл если setVisibleScroll(true)
     */
    public void paint(Graphics g) {
        if(vScroll) g.drawRGB(scroll, 0, 2, wX+wWidth-2, wY+pScroll, 2, sHeight, true);
    }
    
}