package com.cygnusa.hyperm.util;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.warkiz.widget.IndicatorSeekBar;
import com.warkiz.widget.OnSeekChangeListener;
import com.warkiz.widget.SeekParams;

import java.io.File;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

@SuppressLint("ClickableViewAccessibility")
public class RotateAnimationClass implements OnTouchListener {
    public static Timer animationTimer;
    public static int animationPosition = 0;
    private static boolean isAnimating = false;
    boolean isStarted = false;
    private Timer decelerationTimer;
    private Activity activitiy;
    private static Listner360 listner360;
    private static ImageView imageview;

    private float touchStartX = 0f;
    private float touchStartY = 0f;
    private float swipeStartPointX = 0f;
    private float swipeStartPointY = 0f;
    private long swipeStartTime = 0l;
    private long swipeEndTime = 0l;
    private float dragDistance = 0;
    private float dragSenitivity = 0.05f;
    private int animationDirection = 1;
    private boolean cancelDeceleration = false;
    private boolean decelerateAnimation = false;
    private int decelerationSteps = 0;
    private int numberOfAnimationSteps = 0;
    private float startFrameGap = 0f;
    private float actualframeGap = 0f;
    private float animationSpeed = 0f;
    private long DRAGTIME_CUTOFF = 0;
    private long SWIPETIME_CUTOFF = 0;
    private long ANIMATION_FRAMERATE = 30;
    private Animation animSlide;
    FrameLayout frameLayout;
    public static ArrayList<String> imgArr = new ArrayList<>();
    static Handler handler = new Handler();
    IndicatorSeekBar seekBar;
    int oldPosition = 0;
    ImageView imgLeft;
    ImageView imgRight;

    public RotateAnimationClass(Activity activitiy, ArrayList<String> arr, ImageView imageview,
                                boolean loadHorizondally, FrameLayout frame, final IndicatorSeekBar seekBar,
                                ImageView imgLeft, ImageView imgRight) {
        this.imgArr = arr;
        this.imageview = imageview;
        this.activitiy = activitiy;
        decelerateAnimation = true;
        animationSpeed = 1;
        isAnimating = false;
        animationDirection = 1;
        this.frameLayout = frame;
        animationPosition = 0;
        this.seekBar = seekBar;
        this.imgLeft = imgLeft;
        this.imgRight = imgRight;

        this.imageview.setOnTouchListener(RotateAnimationClass.this);

        if (imgArr != null && imgArr.size() > 0) {
            displayImageWithPosition(animationPosition);
            if (imgArr.size() > 0)
                this.seekBar.setMax(imgArr.size());
        }

        this.imgLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (animationPosition == 0) {
                    animationPosition = imgArr.size() - 1;
                }else {
                    animationPosition = animationPosition - 1;
                }
                seekBar.setProgress(animationPosition);
                displayImageSB();
            }
        });

        this.imgRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (animationPosition >= (imgArr.size() - 1)) {
                    animationPosition = 0;
                }else {
                    animationPosition = animationPosition + 1;
                }
                seekBar.setProgress(animationPosition);
                displayImageSB();
            }
        });

        this.seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
            @Override
            public void onSeeking(SeekParams seekParams) {
                if (oldPosition < seekParams.thumbPosition) {
                    int from = animationPosition + 1;
                    int to = seekParams.seekBar.getProgress();
                    int j = 1;
                    for (int i = from; i <= to; i++) {
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                animationPosition = animationPosition + 1;
                                displayImageSB();
                            }
                        }, j * 30);
                        j++;
                    }
                } else if (oldPosition > seekParams.thumbPosition) {
                    int from = animationPosition - 1;
                    int to = seekParams.seekBar.getProgress();
                    int j = 1;
                    for (int i = from; i >= to; i--) {
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                animationPosition = animationPosition - 1;
                                displayImage();
                            }
                        }, j * 30);
                        j++;
                    }
                }
                oldPosition = seekParams.thumbPosition;
            }

            @Override
            public void onStartTrackingTouch(IndicatorSeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(IndicatorSeekBar seekBar) {

            }
        });
    }

    public void stopRotationAnimation() {
        if (animationTimer != null) {
            animationTimer.cancel();
            animationTimer = null;
        }
        cancelDeceleration = true;
        isAnimating = false;

        if (decelerationTimer != null) {
            decelerationTimer.cancel();
            decelerationTimer = null;
        }
        //rotationViewDidStopAnimating
    }

    public void setPositionChangeListener(Listner360 changeListener) {
        this.listner360 = changeListener;
    }

    public void setImage(String image) {
        if (animationTimer != null) {
            stopRotationAnimation();
        }
        cancelDeceleration = true;

        if (decelerationTimer != null) {
            decelerationTimer.cancel();
            decelerationTimer = null;
        }


        Glide.with(activitiy).load(image).into(imageview);
//        imageview.setImageResource(image);


    }

    public void rotateLeft() {
        animationPosition++;
        checkForValidAnimationPosition();
        displayImage();
    }

    public void rotateRight() {
        animationPosition--;
        checkForValidAnimationPosition();
        displayImage();
    }

    public void startRotationAnimationWithDirection(int direction) {
        if (isAnimating) {
            return;
        }
        animationDirection = direction;
        invokeRotationAnimation();
        //rotationViewDidStartAnimating
    }

    public int numberOfImages() {
        if (imgArr != null) {
            return imgArr.size();
        } else {
            return 0;
        }
    }

    private void displayImageWithPosition(int imagePosition) {
        if (imagePosition < imgArr.size()) {
            animationPosition = imagePosition;
            displayImage();
        }
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (animationTimer != null) {
                stopRotationAnimation();
            }
            cancelDeceleration = true;

            if (decelerationTimer != null) {
                decelerationTimer.cancel();
                decelerationTimer = null;
            }
            touchStartX = event.getX();
            swipeStartPointX = event.getX();
            swipeStartTime = System.currentTimeMillis();
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            dragDistance = Math.abs(event.getX() - touchStartX);
            dragDistance *= dragSenitivity;
            if (dragDistance == 0) {
                dragDistance = 1;
            }

            if ((event.getX() > touchStartX) && ((event.getX() - touchStartX) >= (imageview.getMeasuredWidth() / imgArr.size()))) {
                animationDirection = 1;
                animationPosition += dragDistance;

                checkForValidAnimationPosition();
                displayImage();
                touchStartX = event.getX();
                swipeEndTime = System.currentTimeMillis();

                if (swipeEndTime - swipeStartTime > DRAGTIME_CUTOFF) {
                    swipeStartPointX = event.getX();
                }
                swipeStartTime = swipeEndTime;
            } else if ((event.getX() < touchStartX) && ((touchStartX - event.getX()) >= imageview.getMeasuredWidth() / imgArr.size())) {
                animationDirection = -1;
                animationPosition -= dragDistance;
                checkForValidAnimationPosition();
                displayImage();
                touchStartX = event.getX();
                swipeEndTime = System.currentTimeMillis();

                if (swipeEndTime - swipeStartTime > DRAGTIME_CUTOFF) {
                    swipeStartPointX = event.getX();
                }
                swipeStartTime = swipeEndTime;
            }

            /*if (event.getX() > touchStartX) {
                animationDirection = -1;
                animationPosition -= dragDistance;
            } else if (event.getX() < touchStartX) {
                animationDirection = 1;
                animationPosition += dragDistance;
            }*/


        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            float swipeDistance = Math.abs(swipeStartPointX - event.getX());

            long touchEndTime = System.currentTimeMillis();
            if (touchEndTime - swipeEndTime < SWIPETIME_CUTOFF) {

                cancelDeceleration = false;
                int framecount = 25;

                if (swipeDistance / (touchEndTime - swipeStartTime) > 7500) {
                    framecount = 100;
                } else if (swipeDistance / (touchEndTime - swipeStartTime) > 5000) {
                    framecount = 75;
                } else if (swipeDistance / (touchEndTime - swipeStartTime) > 2500) {
                    framecount = 50;
                }

                decelerationSteps = framecount;
                numberOfAnimationSteps = framecount;
                startFrameGap = dragDistance;
                actualframeGap = startFrameGap;

                if (decelerateAnimation) {
                    //rotateviewDidStartDeclarate
                    invokeDeceleration();
                }
            }
        }

        return true;
    }

    private void invokeDeceleration() {
        if (decelerationSteps <= 0 || cancelDeceleration) {
            cancelDeceleration = true;
            decelerationTimer = null;
            return;
        }

        decelerationTimer = new Timer();
        decelerationTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                activitiy.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            decelerateAnimation();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }, ANIMATION_FRAMERATE);
    }

    private void invokeRotationAnimation() {
        if (decelerationTimer != null) {
            decelerationTimer.cancel();
            decelerationTimer = null;
        }
        isAnimating = true;
        animationTimer = new Timer();
        animationTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                activitiy.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        doAnimation();
                    }
                });
            }
        }, ANIMATION_FRAMERATE);
    }

    private void displayImageafter() {
        Log.e("animationPosition", animationPosition + "");
        //imageview.setImageResource(imgArr.get(animationPosition));


    }

    public static void displayImageSB() {
        try {
            // Log.e("displayPosition", imgArr.get(animationPosition) + "");
//            imageview.setImageResource(imgArr.get(animationPosition));
            imageview.setImageURI(Uri.fromFile(new File(imgArr.get(animationPosition-1))));
//            Glide.with(activitiy).load(imgArr.get(animationPosition)).into(imageview);
            //imageview.setImageResource(Integer.parseInt(imgArr.get(animationPosition)));
            //imageview.setImageBitmap(imgArr.get(animationPosition));
            if (listner360 != null) {
                listner360.onStopAnimation();
            }
            handler.removeCallbacksAndMessages(null);
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (listner360 != null) {
                        listner360.setHotspot(animationPosition-1);
                    }
                }
            }, 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void displayImage() {
        try {
            // Log.e("displayPosition", imgArr.get(animationPosition) + "");
//            imageview.setImageResource(imgArr.get(animationPosition));
            imageview.setImageURI(Uri.fromFile(new File(imgArr.get(animationPosition))));
//            Glide.with(activitiy).load(imgArr.get(animationPosition)).into(imageview);
            //imageview.setImageResource(Integer.parseInt(imgArr.get(animationPosition)));
            //imageview.setImageBitmap(imgArr.get(animationPosition));
            if (listner360 != null) {
                listner360.onStopAnimation();
            }
            this.seekBar.setProgress(animationPosition);
            handler.removeCallbacksAndMessages(null);
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (listner360 != null) {
                        listner360.setHotspot(animationPosition);
                    }
                }
            }, 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void decelerateAnimation() {

        try {
            decelerationSteps--;
            animationPosition += 1 * animationDirection * actualframeGap;
            checkForValidAnimationPosition();
            displayImage();

            if (decelerationSteps != 0) {
                actualframeGap = (startFrameGap * (1 - ((float) numberOfAnimationSteps - (float) decelerationSteps) / (float) numberOfAnimationSteps));
            }

            if (actualframeGap < 1) {
                cancelDeceleration = true;
                if (decelerationTimer != null) {
                    decelerationTimer.cancel();
                    decelerationTimer = null;
                }
                //rotationViewDidStopDecelerating
            }
            invokeDeceleration();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void doAnimation() {
        animationPosition += 1 * animationDirection * animationSpeed;
        checkForValidAnimationPosition();
        displayImage();
        invokeRotationAnimation();
    }

    private void checkForValidAnimationPosition() {
        if (animationPosition < 0) {
            animationPosition = (imgArr.size() - 1);
        } else if (animationPosition > (imgArr.size() - 1)) {
            animationPosition = 0;
        }
    }

}
