// spri.h
// sprite texture definition.
#ifndef __spri_h__
#define __spri_h__

#ifndef __tags_h__
#include "tags.h"
#endif

#ifndef __BYTE_SWAPPING_H__
#include "byte_swapping.h"
#endif

#ifndef __ttageditform_h__
#include "TTagEditForm.h"
#endif

#ifndef __myth_defs_h__
#include "myth_defs.h"
#endif

#define SPRITE_TEXTURE_DEFINITION_TAG_TYPE	'spri'
struct sprite_frame_definition
{
	float xy[4][2];
	float st[4][2];
	
	float slot_st[2][2];
	int slot_xy[2];
	int slot_wh[2];
	
	tag texture_stack_tag;
	int stack_num;
	int tex_num;
	
	void* data;
	int frame_num;
	int slot_valid;
	short width, height, channels, padd;	
};

enum
{
	_sprite_sequence_repeats_forever_bit,
	_sprite_sequence_repeats_finite_bit,
	_sprite_sequence_expires_by_time_bit,
	
	NUMBER_OF_SPRITE_SEQUENCE_FLAGS,
	
	_sprite_sequence_repeats_forever_flag = FLAG(_sprite_sequence_repeats_forever_bit),
	_sprite_sequence_repeats_finite_flag  = FLAG(_sprite_sequence_repeats_finite_bit),
	_sprite_sequence_expires_by_time_flag = FLAG(_sprite_sequence_expires_by_time_bit)
	
};

#define MAX_FRAMES_PER_SEQUENCE		256
struct sprite_sequence_definition
{
	int num_frames;
	int probability;
	int time;
	int flags;
	
	int* frames;
	int* ticks;
	float* colors; // num_frames*4 for rgba.
	float* rots;   // rotations for the sequence.
	tag* sound_tags;	// sounds to play on each frame.
	float* scales;
};

enum
{
	_sprite_def_dies_at_end_of_sequence_bit,
	
	NUMBER_OF_SPRITE_DEF_FLAGS,
	
	_sprite_def_dies_at_end_of_sequence_flag = FLAG(_sprite_def_dies_at_end_of_sequence_bit)
};

#define MAX_SPRITE_FRAMES		256
#define MAX_SPRITE_SEQUENCES	8

struct sprite_type_definition
{
	int num_frames;
	int num_sequences;
	int total_sequence_probability;
	int flags;
	
	tag id;
	struct sprite_frame_definition* frames;
	struct sprite_sequence_definition* sequences;
};


void defaultnew_spri( tag_entry* e );
bool read_sprite_type_definition( sprite_type_definition* def, tag id, bool load_textures );
bool save_sprite_type_definition( sprite_type_definition* def, tag id );

bool read_sprite_type_definition( sprite_type_definition* def, tag_entry* e, bool load_textures );
bool save_sprite_type_definition( sprite_type_definition* def, tag_entry* e );

sprite_type_definition* alloc_sprite_type_definition( int num_frames, int num_sequences, int max_frames_per_sequence );
void free_sprite_type_definition( sprite_type_definition* def );
void load_sprite_type_definition_frame_textures( sprite_type_definition* def );
void free_sprite_type_definition_frame_textures( sprite_type_definition* def );
bool sprite_type_definitions_differ( sprite_type_definition* def_a, sprite_type_definition* def_b );

class TspriEditForm : public TTagEditForm {

public:
	
	TspriEditForm( tag_entry* e );
	virtual ~TspriEditForm();
	
	DECLAREDISPATCH
	virtual long DoControlClick( long arg, void* ptr );
	virtual long DoListSelect( int arg, void * );
	virtual long DoListDblClick( int arg, void* );
	
	virtual void CommitToTag();
	virtual void ReloadTag();
	virtual bool NeedCommit();
	
protected:

	void SetValues();
	void GetValues();
	
	void UpdateColors();
	void SetSequenceInfo(int seq );
	void GetSequenceInfo(int seq );
	void SetFrameInfo( int seq, int frame );
	void GetFrameInfo( int seq, int frame );
	void SetBitmapFrame( int view, int frame );
	void RemoveFrameFromSequences( int frame );
	void RemoveSequence( int seq );
	void LoadFrameList( void );
	void LoadSequenceList( void );
	void LoadSequenceFrameList( int seq );
	
	sprite_type_definition* def;
	sprite_type_definition* cur;
	int cur_frame;
	int cur_global_frame;
	int cur_seq;
}; 

#endif