/*
 * 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(AudioSystem::MUSIC,  //TODO parametrize this
            pLibConfig->sampleRate,
            1, // format = PCM 16bits per sample,
            pLibConfig->numChannels,
            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

