package app.youkai.progressview;

import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import java.util.Timer;
import java.util.TimerTask;

class LongTouchHandler implements View.OnTouchListener {

    private IncrementListener incrementListener;
    private Timer timer;
    private int incrementBy;

    LongTouchHandler (IncrementListener incrementListener, int incrementBy) {
        this.incrementListener = incrementListener;
        this.incrementBy = incrementBy;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.isClickable()) {
            /* handle press states */
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                v.setPressed(true);
                timer = new Timer();
                // Initial delay = length of a long press
                timer.schedule(new IncrementTask(0, ViewConfiguration.getLongPressTimeout()), ViewConfiguration.getLongPressTimeout());
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                timer.cancel();
                v.setPressed(false);
            }

            long lengthOfPress = event.getEventTime() - event.getDownTime();
            // If the button has been "tapped" then handle normally
            if (lengthOfPress < ViewConfiguration.getLongPressTimeout()
                && event.getAction() == MotionEvent.ACTION_UP) {
                    incrementListener.increment();
            }

            return true;
        } else {
            /* If the view isn't clickable, let the touch be handled by others. */
            return false;
        }
    }

    void cancelPress() {
        try {
            timer.cancel();
        } catch (Exception e) {
            // Swallow.
        }
    }

    private class IncrementTask extends TimerTask {
        private int count;
        private final long initialDelay;

        IncrementTask (int count, long initialDelay) {
            this.count = count;
            this.initialDelay = initialDelay;
        }

        @Override
        public void run() {
            incrementListener.incrementBy(incrementBy);
            count++;
            timer.schedule(new IncrementTask(count, initialDelay), (long) (newTimerCoefficient(count) * initialDelay));
        }

        private double newTimerCoefficient (int count) {
            // Slow start, minimum delay will be 0.2 * initialDelay
            return 0.2 + Math.exp(-0.3 * count);
        }
    }

}