/*
 * 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 <media/JetPlayer.h>


namespace android
{

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

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

//-------------------------------------------------------------------------------------------------
JetPlayer::~JetPlayer()
{
    ALOGV("~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) {
        ALOGE("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) {
        ALOGE("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) {
        ALOGE("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 parameterize this
            pLibConfig->sampleRate,
            AUDIO_FORMAT_PCM_16_BIT,
            audio_channel_out_mask_from_count(pLibConfig->numChannels),
            (size_t) mTrackBufferSize,
            AUDIO_OUTPUT_FLAG_NONE);

    // create render and playback thread
    {
        Mutex::Autolock l(mMutex);
        ALOGV("JetPlayer::init(): trying to start render thread");
        mThread = new JetPlayerThread(this);
        mThread->run("jetRenderThread", ANDROID_PRIORITY_AUDIO);
        mCondition.wait(mMutex);
    }
    if (mTid > 0) {
        // render thread started, we're ready
        ALOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid);
        mState = EAS_STATE_READY;
    } else {
        ALOGE("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()
{
    ALOGV("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 != 0) {
        mAudioTrack->stop();
        mAudioTrack->flush();
        mAudioTrack.clear();
    }
    if (mAudioBuffer) {
        delete mAudioBuffer;
        mAudioBuffer = NULL;
    }
    mEasData = NULL;

    return EAS_SUCCESS;
}


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

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

    // allocate render buffer
    mAudioBuffer =
        new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS];

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

    while (1) {

        mMutex.lock(); // [[[[[[[[ LOCK ---------------------------------------

        if (mEasData == NULL) {
            mMutex.unlock();
            ALOGV("JetPlayer::render(): NULL EAS data, exiting render.");
            goto threadExit;
        }

        // nothing to render, wait for client thread to wake us up
        while (!mRender)
        {
            ALOGV("JetPlayer::render(): signal wait");
            if (audioStarted) {
                mAudioTrack->pause();
                // we have to restart the playback once we start rendering again
                audioStarted = false;
            }
            mCondition.wait(mMutex);
            ALOGV("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) {
                ALOGE("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
        //ALOGV("JetPlayer::render(): updating state");
        JET_Status(mEasData, &mJetStatus);
        fireUpdateOnStatusChange();
        mPaused = mJetStatus.paused;

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

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

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

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

    }//while (1)

threadExit:
    if (mAudioTrack != NULL) {
        mAudioTrack->stop();
        mAudioTrack->flush();
    }
    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)
{
    ALOGV("JetPlayer::loadFromFile(): path=%s", path);

    Mutex::Autolock lock(mMutex);

    mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE));
    strncpy(mJetFilePath, path, sizeof(mJetFilePath));
    mJetFilePath[sizeof(mJetFilePath) - 1] = '\0';
    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)
{
    ALOGV("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()
{
    ALOGV("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
    ALOGV("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)
{
    ALOGV("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)
{
    ALOGV("JetPlayer::triggerClip clipId=%d", clipId);
    Mutex::Autolock lock(mMutex);
    return JET_TriggerClip(mEasData, clipId);
}

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

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

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


} // end namespace android
