/** @file UtilsMOM.cpp
 *
 * Copyright (C) Espial Limited 2014 - Company confidential - All rights reserved.
 *
 * common helper routines for the RMAI integration
 */

#include "config.h"

#if ENABLE(RMAI)

#include "wtf/text/CString.h"
#include "UtilsMOM.h"

extern "C" {
#include "layers.h"
#include "layers_err.h"
#include "layers_string.h"
#include "cdf/mom_localsystem.h"
}

namespace WebCore {

/* renderer/recorder states/actions */
#define DOM_CONSTANT_MOM_IDLE                           0
#define DOM_CONSTANT_MOM_CONNECTING                     101
#define DOM_CONSTANT_MOM_CONNECTED                      102
#define DOM_CONSTANT_MOM_PLAYING                        103
#define DOM_CONSTANT_MOM_STOPPED                        104
#define DOM_CONSTANT_MOM_FAILED                         105
#define DOM_CONSTANT_MOM_PROBLEM                        106
#define DOM_CONSTANT_MOM_RECORDING                      107
#define DOM_CONSTANT_MOM_SCHEDULED                      108
#define DOM_CONSTANT_MOM_DELETED                        109 /* action */
#define DOM_CONSTANT_MOM_DUE_SOON                       110 /* action */
#define DOM_CONSTANT_MOM_UPDATED                        111 /* action */
#define DOM_CONSTANT_MOM_PARTIAL                        112
#define DOM_CONSTANT_MOM_REMINDER                       113
#define DOM_CONSTANT_MOM_REMINDER_DUE                   114 /* action - deprecated */
#define DOM_CONSTANT_MOM_ADDED                          115 /* action */
#define DOM_CONSTANT_MOM_CANCELLED                      116
#define DOM_CONSTANT_MOM_PLAYING_INTERSTITIAL           117
#define DOM_CONSTANT_MOM_PLAYING_WITHOUT_PRESENTATION   118
#define DOM_CONSTANT_MOM_BUFFERING                      119

/* exception code values as defined in the XML file */
#define DOM_CONSTANT_MOM_OK             0
#define DOM_CONSTANT_MOM_INVALID        1
#define DOM_CONSTANT_MOM_BUSY           2
#define DOM_CONSTANT_MOM_NOTPRESENT     3
#define DOM_CONSTANT_MOM_DISCFULL       4
#define DOM_CONSTANT_MOM_FAILURE        5
#define DOM_CONSTANT_MOM_NOTAUTHORISED  6
#define DOM_CONSTANT_MOM_RATING         7
#define DOM_CONSTANT_MOM_DIALOG         8
#define DOM_CONSTANT_MOM_START_OF_STREAM 9
#define DOM_CONSTANT_MOM_END_OF_STREAM  10
#define DOM_CONSTANT_MOM_TSB_WRAP       11
#define DOM_CONSTANT_MOM_PIN_WRONG      12
#define DOM_CONSTANT_MOM_PIN_LOCKED     13
#define DOM_CONSTANT_MOM_EXPIRED        14

/** Convert from mom_stream_state enumeration to DOM values. Note this
 * is a direct lookup and so musty be kept in step with changes to the
 * mom_stream_state enumeration */
static int s_stream_states[] =
{
    DOM_CONSTANT_MOM_IDLE,      /* mom_stream_IDLE */
    DOM_CONSTANT_MOM_CONNECTING,/* mom_stream_RECORD_STARTING */
    DOM_CONSTANT_MOM_RECORDING, /* mom_stream_RECORDING */
    DOM_CONSTANT_MOM_RECORDING, /* mom_stream_PERSISTING */
    DOM_CONSTANT_MOM_RECORDING, /* mom_stream_CONVERTING */
    DOM_CONSTANT_MOM_FAILED,    /* mom_stream_RECORD_FAILED */
    DOM_CONSTANT_MOM_RECORDING, /* mom_stream_RECORD_STOPPING */
    DOM_CONSTANT_MOM_STOPPED,   /* mom_stream_RECORD_STOPPED */

    DOM_CONSTANT_MOM_CONNECTING,/* mom_stream_CONNECTING */
    DOM_CONSTANT_MOM_CONNECTED, /* mom_stream_CONNECTED */
    DOM_CONSTANT_MOM_PLAYING,   /* mom_stream_PLAYING */
    DOM_CONSTANT_MOM_PLAYING,   /* mom_stream_PLAY_STOPPING */
    DOM_CONSTANT_MOM_STOPPED,   /* mom_stream_PLAY_STOPPED */
    DOM_CONSTANT_MOM_FAILED,    /* mom_stream_PLAY_FAILED */
    DOM_CONSTANT_MOM_PLAYING_INTERSTITIAL,          /* mom_stream_PLAYING_INTERSTITIAL */
    DOM_CONSTANT_MOM_PLAYING_WITHOUT_PRESENTATION,  /* mom_stream_PLAYING_WITHOUT_PRESENTATION */
    DOM_CONSTANT_MOM_BUFFERING                      /* mom_stream_BUFFERING */
};


/** Convert from mom_recording_state enumeration to DOM values. Must
 * correspond with enum mom_recording_state in mom_recording.h */
static int s_recording_states[] =
{
    DOM_CONSTANT_MOM_SCHEDULED, /* mom_recording_SCHEDULED */
    DOM_CONSTANT_MOM_RECORDING, /* mom_recording_RECORDING */
    DOM_CONSTANT_MOM_STOPPED,   /* mom_recording_STOPPED */
    DOM_CONSTANT_MOM_BUSY,      /* mom_recording_BUSY */
    DOM_CONSTANT_MOM_DISCFULL,  /* mom_recording_DISCFULL */
    DOM_CONSTANT_MOM_FAILED,    /* mom_recording_FAILED */
    DOM_CONSTANT_MOM_RECORDING, /* mom_recording_CONVERTING */
    DOM_CONSTANT_MOM_PARTIAL,   /* mom_recording_PARTIAL */
    DOM_CONSTANT_MOM_REMINDER,  /* mom_recording_REMINDER */
    DOM_CONSTANT_MOM_CANCELLED  /* mom_recording_CANCELLED */
};

/** Convert from mom_recording_action enumeration to DOM values. Must
 * correspond with enum mom_recording_action in mom_recording.h */
static int s_recording_actions[] =
{
    DOM_CONSTANT_MOM_ADDED,     /* mom_recordingaction_ADDED */
    DOM_CONSTANT_MOM_DELETED,   /* mom_recordingaction_DELETED */
    DOM_CONSTANT_MOM_DUE_SOON,  /* mom_recordingaction_DUE_SOON */
    DOM_CONSTANT_MOM_UPDATED,   /* mom_recordingaction_UPDATED */
};

static int dom_mom_core_enum_lookup( const int tab[], size_t max, int enumerator )
{
    ASSERT( enumerator >= 0 && (unsigned)enumerator < max );
    NOT_USED( max );
    return tab[enumerator];
}

int UtilsMOM::codeFromRecordingState(mom_recording_state enumerator)
{
    /* special case, unknown state is used with a NULL recording
     * handle to denote a bulk update */
    if ( enumerator == mom_recording_UNKNOWN )
        return DOM_CONSTANT_MOM_UPDATED;

    return dom_mom_core_enum_lookup( s_recording_states,
                                     sizeof( s_recording_states ) / sizeof( *s_recording_states ),
                                     enumerator );
}

int UtilsMOM::codeFromRecordingState(int enumerator)
{
    return UtilsMOM::codeFromRecordingState(static_cast<mom_recording_state>(enumerator));
}
    
mom_recording_state UtilsMOM::recordingStateFromCode(int dom_state)
{
    unsigned int i;
    for ( i = 0; i < sizeof( s_recording_states ) / sizeof( *s_recording_states ); i++ )
    {
        if ( s_recording_states[i] == dom_state )
            return (mom_recording_state)i;
    }
    return mom_recording_UNKNOWN;
}
    
int UtilsMOM::codeFromStreamState( mom_stream_state enumerator )
{
    return dom_mom_core_enum_lookup( s_stream_states,
                                     sizeof( s_stream_states ) / sizeof( *s_stream_states ),
                                     enumerator );
}

int UtilsMOM::codeFromStreamState(int enumerator)
{
    return UtilsMOM::codeFromStreamState(static_cast<mom_stream_state>(enumerator));
}

int UtilsMOM::codeFromRecordingAction( mom_recording_action enumerator )
{
    return dom_mom_core_enum_lookup( s_recording_actions,
                                     sizeof( s_recording_actions ) / sizeof( *s_recording_actions ),
                                     enumerator );
}

int UtilsMOM::codeFromRecordingAction(int enumerator)
{
    return UtilsMOM::codeFromRecordingAction(static_cast<mom_recording_action>(enumerator));
}

bool UtilsMOM::recordingActionIsAddedOrUpdated(mom_recording_action action)
{
    return action == mom_recordingaction_UPDATED || action == mom_recordingaction_ADDED;
}

bool UtilsMOM::recordingActionIsAddedOrUpdated(int action)
{
    return UtilsMOM::recordingActionIsAddedOrUpdated(static_cast<mom_recording_action>(action));
}

/* TODO: we may be able to make this more efficient by doing the
 * conversion from Latin1/UTF-16 within layers_string
 */
layers_string UtilsMOM::LayersStringFromString( const String & str )
{
    return LayersStringFromStringInline(str);
}

String UtilsMOM::StringFromLayersString( layers_string lstr )
{
    return StringFromLayersStringInline(lstr);
}

String UtilsMOM::StringFromLayersStringAndDispose( layers_string lstr )
{
    String str = StringFromLayersString(lstr);
    layers_string_dispose(lstr);
    return str;
}

} // namespace WebCore

#endif // ENABLE(RMAI)
