/*
 * Copyright 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "gestureDetector.h"

//--------------------------------------------------------------------------------
// gestureDetector.cpp
//--------------------------------------------------------------------------------
namespace ndk_helper
{

//--------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// GestureDetector
//--------------------------------------------------------------------------------
GestureDetector::GestureDetector()
{
    dp_factor_ = 1.f;
}

void GestureDetector::SetConfiguration( AConfiguration* config )
{
    dp_factor_ = 160.f / AConfiguration_getDensity( config );
}

//--------------------------------------------------------------------------------
// TapDetector
//--------------------------------------------------------------------------------
GESTURE_STATE TapDetector::Detect( const AInputEvent* motion_event )
{
    if( AMotionEvent_getPointerCount( motion_event ) > 1 )
    {
        //Only support single touch
        return false;
    }

    int32_t action = AMotionEvent_getAction( motion_event );
    unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
    switch( flags )
    {
    case AMOTION_EVENT_ACTION_DOWN:
        down_pointer_id_ = AMotionEvent_getPointerId( motion_event, 0 );
        down_x_ = AMotionEvent_getX( motion_event, 0 );
        down_y_ = AMotionEvent_getY( motion_event, 0 );
        break;
    case AMOTION_EVENT_ACTION_UP:
    {
        int64_t eventTime = AMotionEvent_getEventTime( motion_event );
        int64_t downTime = AMotionEvent_getDownTime( motion_event );
        if( eventTime - downTime <= TAP_TIMEOUT )
        {
            if( down_pointer_id_ == AMotionEvent_getPointerId( motion_event, 0 ) )
            {
                float x = AMotionEvent_getX( motion_event, 0 ) - down_x_;
                float y = AMotionEvent_getY( motion_event, 0 ) - down_y_;
                if( x * x + y * y < TOUCH_SLOP * TOUCH_SLOP * dp_factor_ )
                {
                    LOGI( "TapDetector: Tap detected" );
                    return GESTURE_STATE_ACTION;
                }
            }
        }
        break;
    }
    }
    return GESTURE_STATE_NONE;
}

//--------------------------------------------------------------------------------
// DoubletapDetector
//--------------------------------------------------------------------------------
GESTURE_STATE DoubletapDetector::Detect( const AInputEvent* motion_event )
{
    if( AMotionEvent_getPointerCount( motion_event ) > 1 )
    {
        //Only support single double tap
        return false;
    }

    bool tap_detected = tap_detector_.Detect( motion_event );

    int32_t action = AMotionEvent_getAction( motion_event );
    unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
    switch( flags )
    {
    case AMOTION_EVENT_ACTION_DOWN:
    {
        int64_t eventTime = AMotionEvent_getEventTime( motion_event );
        if( eventTime - last_tap_time_ <= DOUBLE_TAP_TIMEOUT )
        {
            float x = AMotionEvent_getX( motion_event, 0 ) - last_tap_x_;
            float y = AMotionEvent_getY( motion_event, 0 ) - last_tap_y_;
            if( x * x + y * y < DOUBLE_TAP_SLOP * DOUBLE_TAP_SLOP * dp_factor_ )
            {
                LOGI( "DoubletapDetector: Doubletap detected" );
                return GESTURE_STATE_ACTION;
            }
        }
        break;
    }
    case AMOTION_EVENT_ACTION_UP:
        if( tap_detected )
        {
            last_tap_time_ = AMotionEvent_getEventTime( motion_event );
            last_tap_x_ = AMotionEvent_getX( motion_event, 0 );
            last_tap_y_ = AMotionEvent_getY( motion_event, 0 );
        }
        break;
    }
    return GESTURE_STATE_NONE;
}

void DoubletapDetector::SetConfiguration( AConfiguration* config )
{
    dp_factor_ = 160.f / AConfiguration_getDensity( config );
    tap_detector_.SetConfiguration( config );
}

//--------------------------------------------------------------------------------
// PinchDetector
//--------------------------------------------------------------------------------

int32_t PinchDetector::FindIndex( const AInputEvent* event, int32_t id )
{
    int32_t count = AMotionEvent_getPointerCount( event );
    for( uint32_t i = 0; i < count; ++i )
    {
        if( id == AMotionEvent_getPointerId( event, i ) )
            return i;
    }
    return -1;
}

GESTURE_STATE PinchDetector::Detect( const AInputEvent* event )
{
    GESTURE_STATE ret = GESTURE_STATE_NONE;
    int32_t action = AMotionEvent_getAction( event );
    uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
    event_ = event;

    int32_t count = AMotionEvent_getPointerCount( event );
    switch( flags )
    {
    case AMOTION_EVENT_ACTION_DOWN:
        vec_pointers_.push_back( AMotionEvent_getPointerId( event, 0 ) );
        break;
    case AMOTION_EVENT_ACTION_POINTER_DOWN:
    {
        int32_t iIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        vec_pointers_.push_back( AMotionEvent_getPointerId( event, iIndex ) );
        if( count == 2 )
        {
            //Start new pinch
            ret = GESTURE_STATE_START;
        }
    }
        break;
    case AMOTION_EVENT_ACTION_UP:
        vec_pointers_.pop_back();
        break;
    case AMOTION_EVENT_ACTION_POINTER_UP:
    {
        int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        int32_t released_pointer_id = AMotionEvent_getPointerId( event, index );

        std::vector<int32_t>::iterator it = vec_pointers_.begin();
        std::vector<int32_t>::iterator it_end = vec_pointers_.end();
        int32_t i = 0;
        for( ; it != it_end; ++it, ++i )
        {
            if( *it == released_pointer_id )
            {
                vec_pointers_.erase( it );
                break;
            }
        }

        if( i <= 1 )
        {
            //Reset pinch or drag
            if( count != 2 )
            {
                //Start new pinch
                ret = GESTURE_STATE_START | GESTURE_STATE_END;
            }
        }
    }
        break;
    case AMOTION_EVENT_ACTION_MOVE:
        switch( count )
        {
        case 1:
            break;
        default:
            //Multi touch
            ret = GESTURE_STATE_MOVE;
            break;
        }
        break;
    case AMOTION_EVENT_ACTION_CANCEL:
        break;
    }

    return ret;
}

bool PinchDetector::GetPointers( Vec2& v1, Vec2& v2 )
{
    if( vec_pointers_.size() < 2 )
        return false;

    int32_t index = FindIndex( event_, vec_pointers_[0] );
    if( index == -1 )
        return false;

    float x = AMotionEvent_getX( event_, index );
    float y = AMotionEvent_getY( event_, index );

    index = FindIndex( event_, vec_pointers_[1] );
    if( index == -1 )
        return false;

    float x2 = AMotionEvent_getX( event_, index );
    float y2 = AMotionEvent_getY( event_, index );

    v1 = Vec2( x, y );
    v2 = Vec2( x2, y2 );

    return true;
}

//--------------------------------------------------------------------------------
// DragDetector
//--------------------------------------------------------------------------------

int32_t DragDetector::FindIndex( const AInputEvent* event, int32_t id )
{
    int32_t count = AMotionEvent_getPointerCount( event );
    for( uint32_t i = 0; i < count; ++i )
    {
        if( id == AMotionEvent_getPointerId( event, i ) )
            return i;
    }
    return -1;
}

GESTURE_STATE DragDetector::Detect( const AInputEvent* event )
{
    GESTURE_STATE ret = GESTURE_STATE_NONE;
    int32_t action = AMotionEvent_getAction( event );
    int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
    uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
    event_ = event;

    int32_t count = AMotionEvent_getPointerCount( event );
    switch( flags )
    {
    case AMOTION_EVENT_ACTION_DOWN:
        vec_pointers_.push_back( AMotionEvent_getPointerId( event, 0 ) );
        ret = GESTURE_STATE_START;
        break;
    case AMOTION_EVENT_ACTION_POINTER_DOWN:
        vec_pointers_.push_back( AMotionEvent_getPointerId( event, index ) );
        break;
    case AMOTION_EVENT_ACTION_UP:
        vec_pointers_.pop_back();
        ret = GESTURE_STATE_END;
        break;
    case AMOTION_EVENT_ACTION_POINTER_UP:
    {
        int32_t released_pointer_id = AMotionEvent_getPointerId( event, index );

        std::vector<int32_t>::iterator it = vec_pointers_.begin();
        std::vector<int32_t>::iterator it_end = vec_pointers_.end();
        int32_t i = 0;
        for( ; it != it_end; ++it, ++i )
        {
            if( *it == released_pointer_id )
            {
                vec_pointers_.erase( it );
                break;
            }
        }

        if( i <= 1 )
        {
            //Reset pinch or drag
            if( count == 2 )
            {
                ret = GESTURE_STATE_START;
            }
        }
        break;
    }
    case AMOTION_EVENT_ACTION_MOVE:
        switch( count )
        {
        case 1:
            //Drag
            ret = GESTURE_STATE_MOVE;
            break;
        default:
            break;
        }
        break;
    case AMOTION_EVENT_ACTION_CANCEL:
        break;
    }

    return ret;
}

bool DragDetector::GetPointer( Vec2& v )
{
    if( vec_pointers_.size() < 1 )
        return false;

    int32_t iIndex = FindIndex( event_, vec_pointers_[0] );
    if( iIndex == -1 )
        return false;

    float x = AMotionEvent_getX( event_, iIndex );
    float y = AMotionEvent_getY( event_, iIndex );

    v = Vec2( x, y );

    return true;
}

}   //namespace ndkHelper

