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

//#define LOG_NDEBUG 0
#define LOG_TAG "JetPlayer-C"

#include <utils/Log.h>
#include <utils/threads.h>

#include <media/JetPlayer.h>


#ifdef HAVE_GETTID
static pid_t myTid() { return gettid(); }
#else
static pid_t myTid() { return getpid(); }
#endif


namespace android
{

static const int MIX_NUM_BUFFERS = 4;
static const S_EAS_LIB_CONFIG* pLibConfig = NULL;

//-------------------------------------------------------------------------------------------------
JetPlayer::JetPlayer(jobject javaJetPlayer, int maxTracks, int trackBufferSize) :
        mEventCallback(NULL),
        mJavaJetPlayerRef(javaJetPlayer),
        mTid(-1),
        mRender(false),
        mPaused(false),
        mMaxTracks(maxTracks),
        mEasData(NULL),
        mEasJetFileLoc(NULL),
        mAudioTrack(NULL),
        mTrackBufferSize(trackBufferSize)
{
    LOGV("JetPlayer constructor");
    mPreviousJetStatus.currentUserID = -1;
    mPreviousJetStatus.segmentRepeatCount = -1;
    mPreviousJetStatus.numQueuedSegments = -1;
    mPreviousJetStatus.paused = true;
}

//-------------------------------------------------------------------------------------------------
JetPlayer::~JetPlayer()
{
    LOGV("~JetPlayer");
    release();

}

//-------------------------------------------------------------------------------------------------
int JetPlayer::init()
{
    //Mutex::Autolock lock(&mMutex);

    EAS_RESULT result;

    // retrieve the EAS library settings
    if (pLibConfig == NULL)
        pLibConfig = EAS_Config();
    if (pLibConfig == NULL) {
        LOGE("JetPlayer::init(): EAS library configuration could not be retrieved, aborting.");
        return EAS_FAILURE;
    }

    // init the EAS library
    result = EAS_Init(&mEasData);
    if( result != EAS_SUCCESS) {
        LOGE("JetPlayer::init(): Error initializing Sonivox EAS library, aborting.");
        mState = EAS_STATE_ERROR;
        return result;
    }
    // init the JET library with the default app event controller range
    result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG));
    if( result != EAS_SUCCESS) {
        LOGE("JetPlayer::init(): Error initializing JET library, aborting.");
        mState = EAS_STATE_ERROR;
        return result;
    }

    // create the output AudioTrack
    mAudioTrack = new AudioTrack();
    mAudioTrack->set(AUDIO_STREAM_MUSIC,  //TODO parametrize this
            pLibConfig->sampleRate,
            1, // format = PCM 16bits per sample,
            (pLibConfig->numChannels == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
            mTrackBufferSize,
            0);

    // create render and playback thread
    {
        Mutex::Autolock l(mMutex);
        LOGV("JetPlayer::init(): trying to start render thread");
        createThreadEtc(renderThread, this, "jetRenderThread", ANDROID_PRIORITY_AUDIO);
        mCondition.wait(mMutex);
    }
    if (mTid > 0) {
        // render thread started, we're ready
        LOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid);
        mState = EAS_STATE_READY;
    } else {
        LOGE("JetPlayer::init(): failed to start render thread.");
        mState = EAS_STATE_ERROR;
        return EAS_FAILURE;
    }

    return EAS_SUCCESS;
}

void JetPlayer::setEventCallback(jetevent_callback eventCallback)
{
    Mutex::Autolock l(mMutex);
    mEventCallback = eventCallback;
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::release()
{
    LOGV("JetPlayer::release()");
    Mutex::Autolock lock(mMutex);
    mPaused = true;
    mRender = false;
    if (mEasData) {
        JET_Pause(mEasData);
        JET_CloseFile(mEasData);
        JET_Shutdown(mEasData);
        EAS_Shutdown(mEasData);
    }
    if (mEasJetFileLoc) {
        free(mEasJetFileLoc);
        mEasJetFileLoc = NULL;
    }
    if (mAudioTrack) {
        mAudioTrack->stop();
        mAudioTrack->flush();
        delete mAudioTrack;
        mAudioTrack = NULL;
    }
    if (mAudioBuffer) {
        delete mAudioBuffer;
        mAudioBuffer = NULL;
    }
    mEasData = NULL;
    
    return EAS_SUCCESS;
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::renderThread(void* p) {

    return ((JetPlayer*)p)->render();
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::render() {
    EAS_RESULT result = EAS_FAILURE;
    EAS_I32 count;
    int temp;
    bool audioStarted = false;

    LOGV("JetPlayer::render(): entering");

    // allocate render buffer
    mAudioBuffer = 
        new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS];
    if (!mAudioBuffer) {
        LOGE("JetPlayer::render(): mAudioBuffer allocate failed");
        goto threadExit;
    }

    // signal main thread that we started
    {
        Mutex::Autolock l(mMutex);
        mTid = myTid();
        LOGV("JetPlayer::render(): render thread(%d) signal", mTid);
        mCondition.signal();
    }

   while (1) {
    
        mMutex.lock(); // [[[[[[[[ LOCK ---------------------------------------

        if (mEasData == NULL) {
            mMutex.unlock();
            LOGV("JetPlayer::render(): NULL EAS data, exiting render.");
            goto threadExit;
        }
            
        // nothing to render, wait for client thread to wake us up
        while (!mRender)
        {
            LOGV("JetPlayer::render(): signal wait");
            if (audioStarted) { 
                mAudioTrack->pause(); 
                // we have to restart the playback once we start rendering again
                audioStarted = false;
            }
            mCondition.wait(mMutex);
            LOGV("JetPlayer::render(): signal rx'd");
        }
        
        // render midi data into the input buffer
        int num_output = 0;
        EAS_PCM* p = mAudioBuffer;
        for (int i = 0; i < MIX_NUM_BUFFERS; i++) {
            result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
            if (result != EAS_SUCCESS) {
                LOGE("JetPlayer::render(): EAS_Render returned error %ld", result);
            }
            p += count * pLibConfig->numChannels;
            num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
            
             // send events that were generated (if any) to the event callback
            fireEventsFromJetQueue();
        }

        // update playback state
        //LOGV("JetPlayer::render(): updating state");
        JET_Status(mEasData, &mJetStatus);
        fireUpdateOnStatusChange();
        mPaused = mJetStatus.paused;

        mMutex.unlock(); // UNLOCK ]]]]]]]] -----------------------------------

        // check audio output track
        if (mAudioTrack == NULL) {
            LOGE("JetPlayer::render(): output AudioTrack was not created");
            goto threadExit;
        }

        // Write data to the audio hardware
        //LOGV("JetPlayer::render(): writing to audio output");
        if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) {
            LOGE("JetPlayer::render(): Error in writing:%d",temp);
            return temp;
        }

        // start audio output if necessary
        if (!audioStarted) {
            LOGV("JetPlayer::render(): starting audio playback");
            mAudioTrack->start();
            audioStarted = true;
        }

    }//while (1)

threadExit:
    if (mAudioTrack) {
        mAudioTrack->stop();
        mAudioTrack->flush();
    }
    if (mAudioBuffer) {
        delete [] mAudioBuffer;
        mAudioBuffer = NULL;
    }
    mMutex.lock();
    mTid = -1;
    mCondition.signal();
    mMutex.unlock();
    return result;
}


//-------------------------------------------------------------------------------------------------
// fire up an update if any of the status fields has changed
// precondition: mMutex locked
void JetPlayer::fireUpdateOnStatusChange()
{
    if(  (mJetStatus.currentUserID      != mPreviousJetStatus.currentUserID)
       ||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) {
        if(mEventCallback)  {
            mEventCallback(
                JetPlayer::JET_USERID_UPDATE,
                mJetStatus.currentUserID,
                mJetStatus.segmentRepeatCount,
                mJavaJetPlayerRef);
        }
        mPreviousJetStatus.currentUserID      = mJetStatus.currentUserID;
        mPreviousJetStatus.segmentRepeatCount = mJetStatus.segmentRepeatCount;
    }

    if(mJetStatus.numQueuedSegments != mPreviousJetStatus.numQueuedSegments) {
        if(mEventCallback)  {
            mEventCallback(
                JetPlayer::JET_NUMQUEUEDSEGMENT_UPDATE,
                mJetStatus.numQueuedSegments,
                -1,
                mJavaJetPlayerRef);
        }
        mPreviousJetStatus.numQueuedSegments  = mJetStatus.numQueuedSegments;
    }

    if(mJetStatus.paused != mPreviousJetStatus.paused) {
        if(mEventCallback)  {
            mEventCallback(JetPlayer::JET_PAUSE_UPDATE,
                mJetStatus.paused,
                -1,
                mJavaJetPlayerRef);
        }
        mPreviousJetStatus.paused = mJetStatus.paused;
    }

}


//-------------------------------------------------------------------------------------------------
// fire up all the JET events in the JET engine queue (until the queue is empty)
// precondition: mMutex locked
void JetPlayer::fireEventsFromJetQueue()
{
    if(!mEventCallback) {
        // no callback, just empty the event queue
        while (JET_GetEvent(mEasData, NULL, NULL)) { }
        return;
    }

    EAS_U32 rawEvent;
    while (JET_GetEvent(mEasData, &rawEvent, NULL)) {
        mEventCallback(
            JetPlayer::JET_EVENT,
            rawEvent,
            -1,
            mJavaJetPlayerRef);
    }
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::loadFromFile(const char* path)
{
    LOGV("JetPlayer::loadFromFile(): path=%s", path);

    Mutex::Autolock lock(mMutex);

    mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE));
    memset(mJetFilePath, 0, 256);
    strncpy(mJetFilePath, path, strlen(path));
    mEasJetFileLoc->path = mJetFilePath;

    mEasJetFileLoc->fd = 0;
    mEasJetFileLoc->length = 0;
    mEasJetFileLoc->offset = 0;

    EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc);
    if(result != EAS_SUCCESS)
        mState = EAS_STATE_ERROR;
    else
        mState = EAS_STATE_OPEN;
    return( result );
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length)
{
    LOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length);
    
    Mutex::Autolock lock(mMutex);

    mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE));
    mEasJetFileLoc->fd = fd;
    mEasJetFileLoc->offset = offset;
    mEasJetFileLoc->length = length;
    mEasJetFileLoc->path = NULL;
    
    EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc);
    if(result != EAS_SUCCESS)
        mState = EAS_STATE_ERROR;
    else
        mState = EAS_STATE_OPEN;
    return( result );
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::closeFile()
{
    Mutex::Autolock lock(mMutex);
    return JET_CloseFile(mEasData);
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::play()
{
    LOGV("JetPlayer::play(): entering");
    Mutex::Autolock lock(mMutex);

    EAS_RESULT result = JET_Play(mEasData);

    mPaused = false;
    mRender = true;

    JET_Status(mEasData, &mJetStatus);
    this->dumpJetStatus(&mJetStatus);
    
    fireUpdateOnStatusChange();

    // wake up render thread
    LOGV("JetPlayer::play(): wakeup render thread");
    mCondition.signal();

    return result;
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::pause()
{
    Mutex::Autolock lock(mMutex);
    mPaused = true;
    EAS_RESULT result = JET_Pause(mEasData);

    mRender = false;

    JET_Status(mEasData, &mJetStatus);
    this->dumpJetStatus(&mJetStatus);
    fireUpdateOnStatusChange();


    return result;
}


//-------------------------------------------------------------------------------------------------
int JetPlayer::queueSegment(int segmentNum, int libNum, int repeatCount, int transpose,
        EAS_U32 muteFlags, EAS_U8 userID)
{
    LOGV("JetPlayer::queueSegment segmentNum=%d, libNum=%d, repeatCount=%d, transpose=%d",
        segmentNum, libNum, repeatCount, transpose);
    Mutex::Autolock lock(mMutex);
    return JET_QueueSegment(mEasData, segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::setMuteFlags(EAS_U32 muteFlags, bool sync)
{
    Mutex::Autolock lock(mMutex);
    return JET_SetMuteFlags(mEasData, muteFlags, sync);
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::setMuteFlag(int trackNum, bool muteFlag, bool sync)
{
    Mutex::Autolock lock(mMutex);
    return JET_SetMuteFlag(mEasData, trackNum, muteFlag, sync);
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::triggerClip(int clipId)
{
    LOGV("JetPlayer::triggerClip clipId=%d", clipId);
    Mutex::Autolock lock(mMutex);
    return JET_TriggerClip(mEasData, clipId);
}

//-------------------------------------------------------------------------------------------------
int JetPlayer::clearQueue()
{
    LOGV("JetPlayer::clearQueue");
    Mutex::Autolock lock(mMutex);
    return JET_Clear_Queue(mEasData);
}

//-------------------------------------------------------------------------------------------------
void JetPlayer::dump()
{
    LOGE("JetPlayer dump: JET file=%s", mEasJetFileLoc->path);
}

void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus)
{
    if(pJetStatus!=NULL)
        LOGV(">> current JET player status: userID=%d segmentRepeatCount=%d numQueuedSegments=%d paused=%d",
                pJetStatus->currentUserID, pJetStatus->segmentRepeatCount,
                pJetStatus->numQueuedSegments, pJetStatus->paused);
    else
        LOGE(">> JET player status is NULL");
}


} // end namespace android

