/***********************************************************************
  The content of this file includes source code for the sound engine
  portion of the AUDIOKINETIC Wwise Technology and constitutes "Level
  Two Source Code" as defined in the Source Code Addendum attached
  with this file.  Any use of the Level Two Source Code shall be
  subject to the terms and conditions outlined in the Source Code
  Addendum and the End User License Agreement for Wwise(R).

  Version: v2008.2.1  Build: 2821
  Copyright (c) 2006-2008 Audiokinetic Inc.
 ***********************************************************************/

//////////////////////////////////////////////////////////////////////
//
// AkMusicStructs.h
//
// Interactive Music specific structures definitions.
//
//////////////////////////////////////////////////////////////////////
#ifndef _MUSIC_STRUCTURES_H_
#define _MUSIC_STRUCTURES_H_

#include <AK/SoundEngine/Common/AkCommonDefs.h>
#include "PrivateStructures.h"


// Wwise specific types.
// ---------------------------------------

typedef AkUInt32    AkMusicMarkerID;

enum AkMusicMarkerType
{
    MarkerTypeEntry,
    MarkerTypeExit,
    MarkerTypeCustom
};

/* Not used.
enum AkNoteValue
{
    NoteValue_1,
    NoteValue_1_2,
    NoteValue_1_4,
    NoteValue_1_8,
    NoteValue_1_16,
    NoteValue_1_32,
    NoteValue_1_64,
    NoteValue_1_2_triplet,
    NoteValue_1_4_triplet,
    NoteValue_1_8_triplet,
    NoteValue_1_16_triplet,
    NoteValue_1_32_triplet,
    NoteValue_1_64_triplet,
    NoteValue_1_2_dotted,
    NoteValue_1_4_dotted,
    NoteValue_1_8_dotted,
    NoteValue_1_16_dotted,
    NoteValue_1_32_dotted,
    NoteValue_1_64_dotted
};
*/

// Music grid and tempo info, supplied by Wwise.
struct AkMeterInfo
{
    AkReal64    fGridPeriod;        // Grid period (1/frequency) (ms).
    AkReal64    fGridOffset;        // Grid offset (ms).
    AkReal32    fTempo;             // Tempo: Number of Quarter Notes per minute.
    AkUInt8     uTimeSigNumBeatsBar;// Time signature numerator.
    AkUInt8     uTimeSigBeatValue;  // Time signature denominator.
};

// Track audio source info, supplied by Wwise.
struct AkTrackSrcInfo
{
	AkUInt32	trackID;
	AkUniqueID  sourceID;			// ID of the source 
    AkReal64    fPlayAt;            // Play At (ms).
    AkReal64    fBeginTrimOffset;   // Begin Trim offset (ms).
    AkReal64    fEndTrimOffset;     // End Trim offset (ms).
    AkReal64    fSrcDuration;       // Duration (ms).
};

enum AkMusicTrackRanSeqType
{
	AkMusicTrackRanSeqType_Normal	= 0,
	AkMusicTrackRanSeqType_Random	= 1,
	AkMusicTrackRanSeqType_Sequence = 2,
};


// Music transition structures.
// ---------------------------------------------------------

struct AkMusicFade
{
	AkTimeMs				transitionTime;		// how long this should take
	AkCurveInterpolation	eFadeCurve;			// what shape it should have
    AkInt32					iFadeOffset;		// Fade offset. Time on Wwise side, samples on sound engine side.
};

// Extra music object specified for some transitions.
struct AkMusicTransitionObject
{
    AkUniqueID  segmentID;          // Node ID. Can only be a segment.
    AkMusicFade fadeInParams;		// Fade in info. 
    AkMusicFade fadeOutParams;		// Fade out info.
    AkUInt32    bPlayPreEntry   :1;
    AkUInt32    bPlayPostExit   :1;
};

// Music transition rule: Source.
struct AkMusicTransSrcRule
{
    AkMusicFade fadeParams;			// Fade out information.
    AkUInt32 /*AkSyncType*/  eSyncType :NUM_BITS_SYNC_TYPE; // Sync type.
    AkUInt32    bPlayPostExit   :1;
};

enum AkEntryType
{
	EntryTypeEntryMarker,
    EntryTypeSameTime,   // (than the current segment playing, in seconds, from the entry marker).
    EntryTypeUserMarker,
#define NUM_BITS_ENTRY_TYPE (3)
};

struct AkMusicTransDestRule
{
    AkMusicFade fadeParams;			// Fade in info.
    AkMusicMarkerID markerID;       // Marker ID. Applies to EntryTypeUserMarker entry type only.
    AkUniqueID  uJumpToID;          // JumpTo ID (applies to Sequence Containers only).
    AkUInt16 /*AkEntryType*/ eEntryType :NUM_BITS_ENTRY_TYPE; // Entry type. 
    AkUInt16    bPlayPreEntry   :1;
};

//-------------------------------------------------------------------
// Defines.
//-------------------------------------------------------------------
// Used for <ANY> and <NONE> target node IDs. Node IDs generated by
// Wwise must never be one or the other.
#define AK_MUSIC_TRANSITION_RULE_ID_ANY     (-1)
#define AK_MUSIC_TRANSITION_RULE_ID_NONE    (0)

// Transition rule.
struct AkMusicTransitionRule
{
    AkUniqueID  srcID;    // Source (departure) node ID.
    AkUniqueID  destID;   // Destination (arrival) node ID.

    AkMusicTransSrcRule         srcRule;
    AkMusicTransDestRule        destRule;
    AkMusicTransitionObject *   pTransObj;   // Facultative. NULL if not used.
};

// Transition rule.

struct AkWwiseMusicTransitionRule
{
    AkUniqueID  srcID;    // Source (departure) node ID.
    AkUniqueID  destID;   // Destination (arrival) node ID.

	AkMusicFade				srcFade;
    AkUInt32				eSrcSyncType;			// Sync type.
    AkUInt8					bSrcPlayPostExit;

	AkMusicFade				destFade;
    AkUInt32				uDestmarkerID;			// Marker ID. Applies to EntryTypeUserMarker entry type only.
    AkUniqueID				uDestJumpToID;          // JumpTo ID (applies to Sequence Containers only).
    AkUInt16				eDestEntryType;			// Entry type. 
    AkUInt8					bDestPlayPreEntry;

	AkUInt8					bIsTransObjectEnabled;
	AkUniqueID				segmentID;						// Node ID. Can only be a segment.
	AkMusicFade				transFadeIn;
	AkMusicFade				transFadeOut;
    AkUInt8					bPlayPreEntry;
    AkUInt8					bPlayPostExit;
};

//-------------------------------------------------------------------
// Defines.
//-------------------------------------------------------------------
// Music marker. In Editing mode, markers are identified by ID.
// OPTIMISATION: In game mode, could be identified by index.
struct AkMusicMarker
{
    AkMusicMarkerID     id;
    AkUInt32            uPosition;
};

struct AkMusicMarkerWwise // in ms stored on a double
{
    AkMusicMarkerID     id;
    AkReal64            fPosition;
};

enum RSType // must match enum PlayMode, do not reorder
{
	RSType_ContinuousSequence	= 0,
	RSType_StepSequence			= 1,
	RSType_ContinuousRandom		= 2,
	RSType_StepRandom			= 3,
};

// Wwise specific interface
struct AkMusicRanSeqPlaylistItem
{
	AkUniqueID m_SegmentID;
	AkUniqueID m_playlistItemID;

	AkUInt32 m_NumChildren;
	RSType	 m_eRSType;
	AkInt16  m_Loop;
	AkUInt16 m_Weight;
	AkUInt16 m_wAvoidRepeatCount;

	bool m_bIsUsingWeight;
	bool m_bIsShuffle;
};

struct AkMusicSwitchAssoc
{
	AkSwitchStateID switchID;
	AkUniqueID		nodeID;
};

// Used to signify that there is an infinite number of stinger that can play at a time.
#define AK_NO_MAX_NUM_STINGERS -1

class CAkStinger
{
public:
	//Gets() for backward compatibility only, now considered as a struct, so no Get()functions required anumore
	AkTriggerID	TriggerID()	const { return m_TriggerID; }
	AkUniqueID	SegmentID()	const { return m_SegmentID; }
	AkSyncType	SyncPlayAt() const { return m_SyncPlayAt; }
    AkInt32     DontRepeatTime() const { return CAkTimeConv::MillisecondsToSamples( m_DontRepeatTime ); } // Returns samples.
    // OPTIM. Convert once at SetStingers().

	AkTriggerID	m_TriggerID;
	AkUniqueID	m_SegmentID;
	AkSyncType	m_SyncPlayAt;
	AkTimeMs	m_DontRepeatTime;

	AkUInt32	m_numSegmentLookAhead;
};

#endif //_MUSIC_STRUCTURES_H_
