/*
 * Copyright (C) 2010 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.
 */

/* Play implementation */

#include "sles_allinclusive.h"


static SLresult IPlay_SetPlayState(SLPlayItf self, SLuint32 state)
{
    SL_ENTER_INTERFACE

    switch (state) {
    case SL_PLAYSTATE_STOPPED:
    case SL_PLAYSTATE_PAUSED:
    case SL_PLAYSTATE_PLAYING:
        {
        IPlay *thiz = (IPlay *) self;
        unsigned attr = ATTR_NONE;
        result = SL_RESULT_SUCCESS;
#ifdef USE_OUTPUTMIXEXT
        CAudioPlayer *audioPlayer = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
            (CAudioPlayer *) thiz->mThis : NULL;
#endif
        interface_lock_exclusive(thiz);
        SLuint32 oldState = thiz->mState;
        if (state != oldState) {
#ifdef USE_OUTPUTMIXEXT
          for (;; interface_cond_wait(thiz)) {

            // We are comparing the old state (left) vs. new state (right).
            // Note that the old state is 3 bits wide, but new state is only 2 bits wide.
            // That is why the old state is on the left and new state is on the right.
            switch ((oldState << 2) | state) {

            case (SL_PLAYSTATE_STOPPED  << 2) | SL_PLAYSTATE_STOPPED:
            case (SL_PLAYSTATE_PAUSED   << 2) | SL_PLAYSTATE_PAUSED:
            case (SL_PLAYSTATE_PLAYING  << 2) | SL_PLAYSTATE_PLAYING:
               // no-op, and unreachable due to earlier "if (state != oldState)"
                break;

            case (SL_PLAYSTATE_STOPPED  << 2) | SL_PLAYSTATE_PLAYING:
            case (SL_PLAYSTATE_PAUSED   << 2) | SL_PLAYSTATE_PLAYING:
                attr = ATTR_PLAY_STATE;
                // set enqueue attribute if queue is non-empty and state becomes PLAYING
                if ((NULL != audioPlayer) && (audioPlayer->mBufferQueue.mFront !=
                    audioPlayer->mBufferQueue.mRear)) {
                    // note that USE_OUTPUTMIXEXT does not support ATTR_ABQ_ENQUEUE
                    attr |= ATTR_BQ_ENQUEUE;
                }
                FALLTHROUGH_INTENDED;

            case (SL_PLAYSTATE_STOPPED  << 2) | SL_PLAYSTATE_PAUSED:
            case (SL_PLAYSTATE_PLAYING  << 2) | SL_PLAYSTATE_PAUSED:
                // easy
                thiz->mState = state;
                break;

            case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_STOPPED:
                // either spurious wakeup, or someone else requested same transition
                continue;

            case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PAUSED:
            case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PLAYING:
                // wait for someone else to finish their transition, then retry ours
                continue;

            case (SL_PLAYSTATE_PAUSED   << 2) | SL_PLAYSTATE_STOPPED:
            case (SL_PLAYSTATE_PLAYING  << 2) | SL_PLAYSTATE_STOPPED:
                // tell mixer to stop, then wait for mixer to acknowledge the request to stop
                thiz->mState = SL_PLAYSTATE_STOPPING;
                continue;

            default:
                // unexpected state
                assert(SL_BOOLEAN_FALSE);
                result = SL_RESULT_INTERNAL_ERROR;
                break;

            }

            break;
          }
#else
          // Here life looks easy for an Android, but there are other troubles in play land
          thiz->mState = state;
          attr = ATTR_PLAY_STATE;
          // no need to set ATTR_BQ_ENQUEUE or ATTR_ABQ_ENQUEUE
#endif
        }
        // SL_LOGD("set play state %d", state);
        interface_unlock_exclusive_attributes(thiz, attr);
        }
        break;
    default:
        result = SL_RESULT_PARAMETER_INVALID;
        break;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetPlayState(SLPlayItf self, SLuint32 *pState)
{
    SL_ENTER_INTERFACE

    if (NULL == pState) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        interface_lock_shared(thiz);
        SLuint32 state = thiz->mState;
        interface_unlock_shared(thiz);
        result = SL_RESULT_SUCCESS;
#ifdef USE_OUTPUTMIXEXT
        switch (state) {
        case SL_PLAYSTATE_STOPPED:  // as is
        case SL_PLAYSTATE_PAUSED:
        case SL_PLAYSTATE_PLAYING:
            break;
        case SL_PLAYSTATE_STOPPING: // these states require re-mapping
            state = SL_PLAYSTATE_STOPPED;
            break;
        default:                    // impossible
            assert(SL_BOOLEAN_FALSE);
            state = SL_PLAYSTATE_STOPPED;
            result = SL_RESULT_INTERNAL_ERROR;
            break;
        }
#endif
        *pState = state;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
{
    SL_ENTER_INTERFACE

    if (NULL == pMsec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        result = SL_RESULT_SUCCESS;
        IPlay *thiz = (IPlay *) self;
        // even though this is a getter, it can modify state due to caching
        interface_lock_exclusive(thiz);
        SLmillisecond duration = thiz->mDuration;
#ifdef ANDROID
        if (SL_TIME_UNKNOWN == duration) {
            SLmillisecond temp;
            switch (InterfaceToObjectID(thiz)) {
            case SL_OBJECTID_AUDIOPLAYER:
                result = android_audioPlayer_getDuration(thiz, &temp);
                break;
            case XA_OBJECTID_MEDIAPLAYER:
                result = android_Player_getDuration(thiz, &temp);
                break;
            default:
                result = SL_RESULT_FEATURE_UNSUPPORTED;
                break;
            }
            if (SL_RESULT_SUCCESS == result) {
                duration = temp;
                thiz->mDuration = duration;
            }
        }
#else
        // will be set by containing AudioPlayer or MidiPlayer object at Realize, if known,
        // otherwise the duration will be updated each time a new maximum position is detected
#endif
        interface_unlock_exclusive(thiz);
        *pMsec = duration;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
{
    SL_ENTER_INTERFACE

    if (NULL == pMsec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        SLmillisecond position;
        interface_lock_shared(thiz);
#ifdef ANDROID
        // Android does not use the mPosition field for audio and media players
        //  and doesn't cache the position
        switch (IObjectToObjectID((thiz)->mThis)) {
          case SL_OBJECTID_AUDIOPLAYER:
            android_audioPlayer_getPosition(thiz, &position);
            break;
          case XA_OBJECTID_MEDIAPLAYER:
            android_Player_getPosition(thiz, &position);
            break;
          default:
            // we shouldn'be here
            assert(SL_BOOLEAN_FALSE);
        }
#else
        // on other platforms we depend on periodic updates to the current position
        position = thiz->mPosition;
        // if a seek is pending, then lie about current position so the seek appears synchronous
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis;
            SLmillisecond pos = audioPlayer->mSeek.mPos;
            if (SL_TIME_UNKNOWN != pos) {
                position = pos;
            }
        }
#endif
        interface_unlock_shared(thiz);
        *pMsec = position;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_RegisterCallback(SLPlayItf self, slPlayCallback callback, void *pContext)
{
    SL_ENTER_INTERFACE

    IPlay *thiz = (IPlay *) self;
    interface_lock_exclusive(thiz);
    thiz->mCallback = callback;
    thiz->mContext = pContext;
    // omits _attributes b/c noone cares deeply enough about these fields to need quick notification
    interface_unlock_exclusive(thiz);
    result = SL_RESULT_SUCCESS;

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
{
    SL_ENTER_INTERFACE

    if (eventFlags & ~(SL_PLAYEVENT_HEADATEND | SL_PLAYEVENT_HEADATMARKER |
            SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADMOVING | SL_PLAYEVENT_HEADSTALLED)) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        interface_lock_exclusive(thiz);
        if (thiz->mEventFlags != eventFlags) {
#ifdef USE_OUTPUTMIXEXT
            // enabling the "head at new position" play event will postpone the next update event
            if (!(thiz->mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) &&
                    (eventFlags & SL_PLAYEVENT_HEADATNEWPOS)) {
                thiz->mFramesSincePositionUpdate = 0;
            }
#endif
            thiz->mEventFlags = eventFlags;
            interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
        } else {
            interface_unlock_exclusive(thiz);
        }
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetCallbackEventsMask(SLPlayItf self, SLuint32 *pEventFlags)
{
    SL_ENTER_INTERFACE

    if (NULL == pEventFlags) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        interface_lock_shared(thiz);
        SLuint32 eventFlags = thiz->mEventFlags;
        interface_unlock_shared(thiz);
        *pEventFlags = eventFlags;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
{
    SL_ENTER_INTERFACE

    if (SL_TIME_UNKNOWN == mSec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        bool significant = false;
        interface_lock_exclusive(thiz);
        if (thiz->mMarkerPosition != mSec) {
            thiz->mMarkerPosition = mSec;
            if (thiz->mEventFlags & SL_PLAYEVENT_HEADATMARKER) {
                significant = true;
            }
        }
        if (significant) {
            interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
        } else {
            interface_unlock_exclusive(thiz);
        }
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_ClearMarkerPosition(SLPlayItf self)
{
    SL_ENTER_INTERFACE

    IPlay *thiz = (IPlay *) self;
    bool significant = false;
    interface_lock_exclusive(thiz);
    // clearing the marker position is equivalent to setting the marker to SL_TIME_UNKNOWN
    if (thiz->mMarkerPosition != SL_TIME_UNKNOWN) {
        thiz->mMarkerPosition = SL_TIME_UNKNOWN;
        if (thiz->mEventFlags & SL_PLAYEVENT_HEADATMARKER) {
            significant = true;
        }
    }
    if (significant) {
        interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
    } else {
        interface_unlock_exclusive(thiz);
    }
    result = SL_RESULT_SUCCESS;

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
{
    SL_ENTER_INTERFACE

    if (NULL == pMsec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        interface_lock_shared(thiz);
        SLmillisecond markerPosition = thiz->mMarkerPosition;
        interface_unlock_shared(thiz);
        *pMsec = markerPosition;
        if (SL_TIME_UNKNOWN == markerPosition) {
            result = SL_RESULT_PRECONDITIONS_VIOLATED;
        } else {
            result = SL_RESULT_SUCCESS;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
{
    SL_ENTER_INTERFACE

    if (0 == mSec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        bool significant = false;
        interface_lock_exclusive(thiz);
        if (thiz->mPositionUpdatePeriod != mSec) {
            thiz->mPositionUpdatePeriod = mSec;
#ifdef USE_OUTPUTMIXEXT
            if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
                CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis;
                SLuint32 frameUpdatePeriod = ((long long) mSec *
                    (long long) audioPlayer->mSampleRateMilliHz) / 1000000LL;
                if (0 == frameUpdatePeriod) {
                    frameUpdatePeriod = ~0;
                }
                thiz->mFrameUpdatePeriod = frameUpdatePeriod;
                // setting a new update period postpones the next callback
                thiz->mFramesSincePositionUpdate = 0;
            }
#endif
            if (thiz->mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) {
                significant = true;
            }
        }
        if (significant) {
            interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
        } else {
            interface_unlock_exclusive(thiz);
        }
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IPlay_GetPositionUpdatePeriod(SLPlayItf self, SLmillisecond *pMsec)
{
    SL_ENTER_INTERFACE

    if (NULL == pMsec) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IPlay *thiz = (IPlay *) self;
        interface_lock_shared(thiz);
        SLmillisecond positionUpdatePeriod = thiz->mPositionUpdatePeriod;
        interface_unlock_shared(thiz);
        *pMsec = positionUpdatePeriod;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static const struct SLPlayItf_ IPlay_Itf = {
    IPlay_SetPlayState,
    IPlay_GetPlayState,
    IPlay_GetDuration,
    IPlay_GetPosition,
    IPlay_RegisterCallback,
    IPlay_SetCallbackEventsMask,
    IPlay_GetCallbackEventsMask,
    IPlay_SetMarkerPosition,
    IPlay_ClearMarkerPosition,
    IPlay_GetMarkerPosition,
    IPlay_SetPositionUpdatePeriod,
    IPlay_GetPositionUpdatePeriod
};

void IPlay_init(void *self)
{
    IPlay *thiz = (IPlay *) self;
    thiz->mItf = &IPlay_Itf;
    thiz->mState = SL_PLAYSTATE_STOPPED;
    thiz->mDuration = SL_TIME_UNKNOWN;  // will be set by containing player object
    thiz->mPosition = (SLmillisecond) 0;
    thiz->mCallback = NULL;
    thiz->mContext = NULL;
    thiz->mEventFlags = 0;
    thiz->mMarkerPosition = SL_TIME_UNKNOWN;
    thiz->mPositionUpdatePeriod = 1000; // per spec
#ifdef USE_OUTPUTMIXEXT
    thiz->mFrameUpdatePeriod = 0;   // because we don't know the sample rate yet
    thiz->mLastSeekPosition = 0;
    thiz->mFramesSinceLastSeek = 0;
    thiz->mFramesSincePositionUpdate = 0;
#endif
}
