#include "globals.h"
#include "SDL.h"
//#include <SDL_net.h>
#include <string.h>
#include "BlinkenLib.h"
#include "bxxstream.h"
#include "drawprimitives.h"
#include "globals.h"
#include "BlinkenMovie.h"

// global
Uint32 currentBXXMovieFrameNum;

// more or less local
Uint32 bxxLastTick;
Uint32 bxxLastFrameTick;

stBlinkenMovie * pMovie;

void initBXXMovie(char * buffer) {
	// Reset frame number
	currentBXXMovieFrameNum = 0;
	bxxLastFrameTick = 0;

	char fullfname[2048];
	sprintf(fullfname, "movies/%s",&buffer[0]);
	//sprintf(fullfname, "%s", "gewaber.blm");
	pMovie = BlinkenMovieLoad(fullfname);
	if ((pMovie) == NULL) {
		printf("%s not found\n",fullfname);
        	fprintf(stderr, "%s not found\n",fullfname);
	}
	
	SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
	bxxLastTick = SDL_GetTicks();
	
}

void deInitBXXMovie() {
	// This MUST stop the movie, no matter if it's finished or still running
	BlinkenMovieFree(pMovie);
}

Uint32 BlinkenColorizerSolid(Uint32 step, Uint32 channels, Uint32 c, Uint32 maxval /* max 254 */)
{
  Uint32 substep, updown, chan;
  step %= channels * 2 * maxval;
  substep = step % maxval;
  updown = (step / maxval) % 2;
  chan = (step / maxval) / 2;
  if( updown == 0 ) {
    if( c == chan )
      return maxval+1;
    else if( c == (chan + 1) % channels )
      return substep;
    else
      return 0;
  } else {
    if( c == chan )
      return (maxval + 1) - substep;
    else if( c == (chan + 1) % channels )
      return (maxval + 1);
    else
      return 0;
  }
}

Uint32 playBXXMovie(bool matrixMode) {
	Uint32 tick = SDL_GetTicks();
	if(bxxLastTick > tick) {
		return true;
	}

	
	// Lock Surface if needed
	if (SDL_MUSTLOCK(gScreen))
		if (SDL_LockSurface(gScreen) < 0)
			return true;

	Uint32 /*len, */ framescount;
	//write pMovie on top
	framescount = BlinkenMovieGetFrameCnt(pMovie);
	if (pMovie!=NULL && currentBXXMovieFrameNum<=framescount) {
		stBlinkenFrame * pFrame = 0;
		SDL_Event event;
		if(bxxLastTick <= tick && currentBXXMovieFrameNum<=framescount) {
			pFrame = BlinkenMovieGetFrame(pMovie, currentBXXMovieFrameNum++);
			bxxLastTick += BlinkenFrameGetDuration(pFrame);/* event loop */
		}
		Uint32 height = BlinkenFrameGetHeight( pFrame );
		Uint32 width = BlinkenFrameGetWidth( pFrame );
		Uint32 rectx = SCREEN_WIDTH/width;
		Uint32 recty = SCREEN_HEIGHT/height;
		Sint32 dx = SCREEN_WIDTH-(width*rectx);
		//Sint32 dy = SCREEN_HEIGHT-(height*recty);
		Uint32 channels = BlinkenFrameGetChannels( pFrame );
		Uint32 maxval = BlinkenFrameGetMaxval( pFrame );
		for(Uint32 y = 0; y < height; y++) {
			for(Uint32 x = 0; x < width; x++) {
				SDL_PollEvent(&event);
				//printf("%d pressed\n",event.jbutton.button);
					switch(event.type) {
						case SDL_JOYBUTTONDOWN:
							switch(event.jbutton.button) {
								case 2: // X pressed 
									//printf("X was pressed\n");
									return false;
									break;
								case 7: // L pressed 
									//printf("L was pressed\n");
									return false;
									break;
							}
							break;
						case SDL_JOYBUTTONUP:
							switch(event.jbutton.button) {
								case 2: // X released 
									//printf("X was released\n");
									return false;
									break;
								case 7: // L released 
									printf("L was released\n");
									return false;
									break;
							}
							break;
						case SDL_QUIT:
							return 2;
							break;

					}
				if (maxval == 1 && channels == 1 && matrixMode) {
					// Klassisches S/W Viedeo -> lass es uns ein bisschen farbig gestalten :-)
					unsigned long colorRGB = BlinkenFrameGetColor( pFrame, y, x );
					if (colorRGB > 0) {
						colorRGB = 1;
					}
					Uint32 rot=0, gruen=0, blau=0;
					if (colorRGB == 1) {
						Uint32 speed = 23;
						rot=BlinkenColorizerSolid(currentBXXMovieFrameNum*speed, 3, 0, 254);
						gruen=BlinkenColorizerSolid(currentBXXMovieFrameNum*speed, 3, 1, 254);
						blau=BlinkenColorizerSolid(currentBXXMovieFrameNum*speed, 3, 2, 254);
					}
					colorRGB = (rot*256*256) + (gruen*256) + (blau);
					drawrect((x * rectx)+1+dx/2, (y * recty)+1, rectx-1, recty-1, colorRGB);
					//printf("%d, %d, %d, %d, %ld, %x, %d\n",x * rectx, y * recty, dx, dy, colorRGB, fpxl, maxval );
				} else if (maxval == 15 && channels == 1 && matrixMode) {
					// Klassisches Graustufen Viedeo -> lass es uns ein bisschen farbig gestalten :-)
					unsigned long colorRGB = BlinkenFrameGetColor( pFrame, y, x );
					//if (colorRGB == 0) {
					//	colorRGB = 1;
					//}
					Uint32 rot=0, gruen=0, blau=0;
					//if (colorRGB != 0) {
						Uint32 speed = 254;
						rot=BlinkenColorizerSolid(colorRGB*speed+currentBXXMovieFrameNum, 3, 0, maxval);
						gruen=BlinkenColorizerSolid(colorRGB*speed+currentBXXMovieFrameNum, 3, 1, maxval);
						blau=BlinkenColorizerSolid(colorRGB*speed+currentBXXMovieFrameNum, 3, 2, maxval);
					//}
					colorRGB = (rot*256*256) + (gruen*256) + (blau);
					drawrect((x * rectx)+1+dx/2, (y * recty)+1, rectx-1, recty-1, colorRGB);
					//printf("%d, %d, %d, %d, %ld, %x, %d\n",x * rectx, y * recty, dx, dy, colorRGB, fpxl, maxval );
				} else {
					// Kein Klassisches S/W Viedeo -> BlinkenLib wird uns passende Farbwerte liefern
					unsigned long colorRGB = BlinkenFrameGetColor( pFrame, y, x );
					//unsigned char pxl = BlinkenFrameGetPixel( pFrame, y, x, 2 );
					//printf("%d, %d, %ld, %x\n", channels, maxval, colorRGB, pxl);
					drawrect((x * rectx)+1+dx/2, (y * recty)+1, rectx-1, recty-1, colorRGB);
				}

			}
		}
	} else {
		return false;
	}

	if (SDL_MUSTLOCK(gScreen)) 
		SDL_UnlockSurface(gScreen);

	SDL_Flip(gScreen); /* Update whole screen */

	return true;
}

