package com.adealink.weparty.commonui.widget.slide.touch

import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import com.adealink.weparty.commonui.widget.slide.Slide
import com.adealink.weparty.commonui.widget.slide.SlideBuilder
import com.adealink.weparty.commonui.widget.slide.SlideListener
import kotlin.math.abs

internal class SlideTouchConsumer(
    private val builder: SlideBuilder,
    private val notifier: SlideListener,

    slideUpLength: Float = 0f,
    slideDownLength: Float = 0f,
    slideLeftLength: Float = 0f,
    slideRightLength: Float = 0f
) {

    private val touchSlop = ViewConfiguration.get(builder.mSliderView.context).scaledPagingTouchSlop
    private var mStartPositionY: Float = 0f
    private var mStartPositionX: Float = 0f

    private val slideUpTouchConsumer = SlideUpTouchConsumer(builder, notifier, slideUpLength)
    private val slideDownTouchConsumer = SlideDownTouchConsumer(builder, notifier, slideDownLength)
    private val slideLeftTouchConsumer = SlideLeftTouchConsumer(builder, notifier, slideLeftLength)
    private val slideRightTouchConsumer = SlideRightTouchConsumer(builder, notifier, slideRightLength)

    private var slideDir: Slide.SlideDirection? = null
    fun onTouch(v: View, event: MotionEvent): Boolean {
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                slideDir = null
                mStartPositionX = event.rawX
                mStartPositionY = event.rawY
                if (Slide.SlideDirection.isUp(builder.mSlideDirection.dir)) {
                    slideUpTouchConsumer.onSlide(v, event)
                }
                if (Slide.SlideDirection.isDown(builder.mSlideDirection.dir)) {
                    slideDownTouchConsumer.onSlide(v, event)
                }

                if (Slide.SlideDirection.isLeft(builder.mSlideDirection.dir)) {
                    slideLeftTouchConsumer.onSlide(v, event)
                }

                if (Slide.SlideDirection.isRight(builder.mSlideDirection.dir)) {
                    slideRightTouchConsumer.onSlide(v, event)
                }
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                if ((slideDir == null || slideDir == Slide.SlideDirection.UP) && Slide.SlideDirection.isUp(builder.mSlideDirection.dir)) {
                    if (trySlide(v, event, slideUpTouchConsumer, slideDownTouchConsumer)) {
                        return true
                    }
                }
                if ((slideDir == null || slideDir == Slide.SlideDirection.DOWN) && Slide.SlideDirection.isDown(builder.mSlideDirection.dir)) {
                    if (trySlide(v, event, slideDownTouchConsumer, slideUpTouchConsumer)) {
                        return true
                    }
                }

                if ((slideDir == null || slideDir == Slide.SlideDirection.LEFT) && Slide.SlideDirection.isLeft(builder.mSlideDirection.dir)) {
                    if (trySlide(v, event, slideLeftTouchConsumer, slideRightTouchConsumer)) {
                        return true
                    }
                }

                if ((slideDir == null || slideDir == Slide.SlideDirection.RIGHT) && Slide.SlideDirection.isRight(builder.mSlideDirection.dir)) {
                    if (trySlide(v, event, slideRightTouchConsumer, slideLeftTouchConsumer)) {
                        return true
                    }
                }
                return false
            }

            MotionEvent.ACTION_UP -> {
                if (slideDir == Slide.SlideDirection.UP && Slide.SlideDirection.isUp(builder.mSlideDirection.dir)) {
                    if (slideUpTouchConsumer.onSlide(v, event)) {
                        return true
                    }
                }
                if (slideDir == Slide.SlideDirection.DOWN && Slide.SlideDirection.isDown(builder.mSlideDirection.dir)) {
                    if (slideDownTouchConsumer.onSlide(v, event)) {
                        return true
                    }
                }

                if (slideDir == Slide.SlideDirection.LEFT && Slide.SlideDirection.isLeft(builder.mSlideDirection.dir)) {
                    if (slideLeftTouchConsumer.onSlide(v, event)) {
                        return true
                    }
                }

                if (slideDir == Slide.SlideDirection.RIGHT && Slide.SlideDirection.isRight(builder.mSlideDirection.dir)) {
                    if (slideRightTouchConsumer.onSlide(v, event)) {
                        return true
                    }
                }
                if (abs(mStartPositionX - event.rawX) < touchSlop && abs(mStartPositionY - event.rawY) < touchSlop) {
                    notifier.performClick(event)
                }
                slideDir = null
                return false
            }
        }
        return false
    }

    fun isAnimationRunning(): Boolean {
        return slideUpTouchConsumer.mAnimationProcessor.isAnimationRunning
                || slideDownTouchConsumer.mAnimationProcessor.isAnimationRunning
                || slideLeftTouchConsumer.mAnimationProcessor.isAnimationRunning
                || slideRightTouchConsumer.mAnimationProcessor.isAnimationRunning

    }

    private fun trySlide(v: View, event: MotionEvent, vararg consumers: AbsTouchConsumer): Boolean {
        if (consumers.isEmpty()) {
            return false
        }
        for (consumer in consumers) {
            if (!builder.mSlideDirection.isSameDir(consumer.dir)) {
                continue
            }
            if (consumer.onSlide(v, event)) {
                slideDir = consumer.dir
                return true
            }
        }
        slideDir = null
        return false
    }

}
