//--------------------------------------------------------------------------//
// iq . 2003/2008 . code for 64 kb intros by RGBA                           //
//--------------------------------------------------------------------------//


#include "sys/msys.h"
#include "planets/planets.h"
#include "scroller/scroller.h"
#include "scroller/introText.h"
#include "sys/extra/msys_extra.h"
#include "resources/resource.h"
#include "intro.h"
#include "minifmod/Music.h"

typedef struct
{
    long    mTo;
	int     mSeed;
}IntroObject;

GLfloat fAspect;
FMUSIC_MODULE* mod;
static IntroObject intro;
float frames = 0.0f;
int _noMusic;
SCREEN_INFO* screen;
planets* _planets;
introText* _introText;
scroller* _scroller;
bmFont *font;

int patternNum = -1;
int prevPatternNum = -1;
int rowNum = -1;
int prevRowNum = -1;
float angle =0;


int intro_init(int nomusic, IntroProgressDelegate *pd, SCREEN_INFO *screenInfo )
{
	_noMusic = false;//nomusic;
    // progress report, (from 0 to 200)
    pd->func( pd->obj, 0 );

	screen = screenInfo;

    // init your stuff here (mzk player, intro, ...)
    // remember to call pd->func() regularly to update the loading bar

    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(screenInfo->height == 0)
        screenInfo->height = 1;

    glViewport(0, 0, screenInfo->width, screenInfo->height);
        
	glShadeModel( GL_SMOOTH );
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	glClearColor( 0, 0, 0, 0 );

    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	
    // Set the clipping volume
	if (screenInfo->widescreen)
	{
		gluPerspective(30.0, 1.77f, 1.0, 10000.0);
	}else{
		gluPerspective(30.0, screenInfo->aspect, 1.0, 10000.0);
	}
    
        
    pd->func( pd->obj, 50 );

    intro.mTo = msys_timerGet();

	//_noMusic = true;
	
	font = bmFontMaker::MakeFont();

	_introText = new introText(font);

	msys_debugPrintf("* INIT SCROLLER\n");
	_scroller = new scroller(font);

	msys_debugPrintf("* INIT PLANETS\n");
	_planets = new planets(_introText);
	pd->func( pd->obj, 60 );


	pd->func( pd->obj, 100 );
	if (!_noMusic)
	{
		msys_debugPrintf("* INIT MUSIC\n");
		// load and play XM file from resource
		mod = loadAndPlayMod(IDR_XMAUDIO1);
		pd->func( pd->obj, 200 );
	}
	return 1;
}

void intro_end( void )
{    
	StopMod(mod);
    // deallicate your stuff here
}

int intro_do( void )
{
    float time = (1.0f/1000.0f) * (float)(msys_timerGet() - intro.mTo);
	bool hitBeat1 = false;
	bool hitBeat2 = false;

	//time += 60;

	// detect beat
	// pattern number
	if (!_noMusic)
	{
		if (prevRowNum!=rowNum)
		{
			prevRowNum = rowNum;
		}
		rowNum = FMUSIC_GetRow(mod);
		int order = FMUSIC_GetOrder(mod);

		// pattern number
		if (prevPatternNum!=patternNum)
		{
			prevPatternNum = patternNum;
		}
		patternNum = mod->orderlist[order];

		FMUSIC_PATTERN *pattern = &mod->pattern[patternNum];
		int numChans = mod->numchannels;
		FMUSIC_NOTE *notes = &pattern->data[rowNum*numChans];
		
		// sample num - chan 3
		//msys_debugPrintf("pn %d\n", patternNum);

		if (rowNum != prevRowNum && notes[25].number == 32)
		{
			// god rays
			_planets->StartGodRays(time);
		}

		if (rowNum != prevRowNum && notes[25].number == 33)
		{
			// START PLANETS
			//_planets->StartSunspots(time);
			_planets->MovePlanetsOutFromSun(time);
		}

		if (rowNum != prevRowNum && notes[26].number == 34)
		{
			// sunspots
			_planets->StartSunspots(time);
		}

		if (rowNum != prevRowNum && notes[22].number == 0x0B)
		{
			// clap/snare
		}

		if (rowNum != prevRowNum && notes[20].number == 0x09)
		{
			// bass/kick
			_planets->EffectKickDrum(time);
		}

		if (rowNum != prevRowNum && notes[21].number == 0x0A)
		{
			// lazer			
		}

		if (rowNum != prevRowNum && (notes[28].number == 0x1A || notes[29].number == 0x1A || notes[30].number == 0x1A || notes[31].number == 0x1A) )
		{
			// chime
			_planets->EffectChime(time);
		}
	}

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	_planets->Draw(time);
	_scroller->Draw(time);
	//_ft->Draw(frames);

	frames+=1.0f;	

	return( 0 );
}