// BlinkenSisters - Hunt for the Lost Pixels
//     Bringing back the fun of the 80s
//
// (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
//
// See License.txt for licensing information
//


#include "../globals.h"
#include "guihandler.h"
#include "../memops.h"
#include "../errorhandler.h"
#include "../drawprimitives.h"
#include "../blending.h"
#include "../showtext.h"
#include "blinkensound.h"
#include "../engine.h"
#include <stdio.h>
#include <string.h>

SDL_Surface* guibg = 0;
SDL_Surface* buttons[5];
bool mouseShown = false;
Sint32 mouseX = 100;
Sint32 mouseY = 100;
bool buttonMouseOver[5];
//char* titleDisplay[] = {"Intro", "Menu", "Orient"};
//char* titleFile[] = {"introMusic.ogg", "menuMusic.ogg", "sisters_orient.ogg"};
Sint32 maxSnd = -1;
Sint32 curSnd = 0;
double scrolloffset = SCR_WIDTH / 2 * -1;

TITLES titles[100];

void initGUI(char * playlist) {

	char fullfname[MAX_FNAME_LENGTH];
	sprintf(fullfname, "%s", configGetPath("blinkenplayerbg.bmp"));
	SDL_Surface* temp = IMG_Load(fullfname);
	if(!temp) {
		DIE(ERROR_IMAGE_READ, fullfname);
	}
	guibg = SDL_DisplayFormat(temp);
	SDL_FreeSurface(temp);
	
	const char* buttonfiles[] = {"player_prev.bmp",
	                     "player_stop.bmp",
	                     "player_play.bmp",
	                     "player_pause.bmp",
	                     "player_next.bmp"};

    for(Uint32 i = 0; i < 5; i++) {
        sprintf(fullfname, "%s", configGetPath(buttonfiles[i]));
	    temp = IMG_Load(fullfname);
    	 if(!temp) {
             DIE(ERROR_IMAGE_READ, fullfname);
         }
	     buttons[i] = SDL_DisplayFormat(temp);
	     SDL_FreeSurface(temp);
	     buttonMouseOver[i] = false;
     }

    if ( playlist == NULL) {
	/* Play the blinkensisters sounds. No user defined playlist */ 
	FILE* fh = fopen(configGetPath("playersounds.dat"), "r");
	if(!fh) {
            DIE(ERROR_FILE_READ, configGetPath("playersounds.dat"));
	}

	char line[1001];
	char* tmpchar;
	char* tmpchar2;
	while(!feof(fh)) {
		maxSnd++;
		if(!fgets(line, 1000, fh)) {
			break;
		}
		while((tmpchar = strstr(line, "\n"))) {
			*tmpchar = 0;
		}
		while((tmpchar = strstr(line, "\r"))) {
			*tmpchar = 0;
		}
		
		
		if(!(tmpchar = strstr(line, "|"))) {
			DIE(ERROR_HTTPTOC, "1|2");
		}
		*tmpchar = 0;
		sprintf(titles[maxSnd].name, "%s", line);
		tmpchar++;
		tmpchar2 = tmpchar;
		
		if(!(tmpchar = strstr(tmpchar, "|"))) {
			DIE(ERROR_HTTPTOC, "2|3");
		}
		*tmpchar = 0;
		sprintf(titles[maxSnd].fname, "%s", tmpchar2);
		tmpchar++;
		tmpchar2 = tmpchar;
		
		sprintf(titles[maxSnd].scrolltext, "%s", tmpchar2);
		soundLoad(maxSnd, titles[maxSnd].fname);
    	}
    	fclose(fh);
    } else {
	/* Playlist != NULL. Play the songs in the playlist */
	/* FIXME: Currently only Filenames, no HTTP-URLs allowed */
	printf("Playlsit: %s\n",playlist);
	FILE* fh = fopen(playlist, "r");
	if(!fh) {
            DIE(ERROR_FILE_READ, playlist);
        }
	char line[1001];
	char* tmpchar;
	while(!feof(fh)) {
		maxSnd++;
		if(!fgets(line, 1000, fh)) {
			break;
		}
		printf("line: %s\n",line);
		while((tmpchar = strstr(line, "\n"))) {
			*tmpchar = 0;
		}
		while((tmpchar = strstr(line, "\r"))) {
			*tmpchar = 0;
		}
		
		printf("Zeile: %s\n",line);
		/* FIXME: Use Information from Ogg-tags for the scrolltest and name */
		sprintf(titles[maxSnd].name, "File: %d", maxSnd);
		sprintf(titles[maxSnd].fname, "%s", line);
		sprintf(titles[maxSnd].scrolltext, "Playing File number %d. Hope you like it.", maxSnd);
		titles[maxSnd].sdlmusic = Mix_LoadMUS(titles[maxSnd].fname);
		if(!titles[maxSnd].sdlmusic) {
			DIE(ERROR_SOUND_READ, titles[maxSnd].fname);
		}
    	}
    	fclose(fh);
    }
    
}

void deInitGUI() {
	SDL_FreeSurface(guibg);
	guibg = 0;
}

void showGUI() {
	

	// Lock screen
	if (SDL_MUSTLOCK(gScreen))
		if (SDL_LockSurface(gScreen) < 0) 
			return;


	// Lock guibg
	if (SDL_MUSTLOCK(guibg))
		if (SDL_LockSurface(guibg) < 0) 
			return;

	Uint32 pitch_bg = gScreen->pitch / 4;	
	
	// Copy the background into the bigger surface
	Uint32 bigpitch = gScreen->pitch;
	Uint32 bigpitchBG = guibg->pitch;
	
	long fc_src_long = (long)guibg->pixels;
	long fc_dst_long = (long)gScreen->pixels;
	
	for(Uint32 j=0; j < SCR_HEIGHT; j++) {
		fc_src = (fastcopy *)fc_src_long;
		fc_dest = (fastcopy *)fc_dst_long;
		*fc_dest = *fc_src;
		fc_dst_long += bigpitch;
		fc_src_long += bigpitchBG;
	}

	// Unlock guibg
	if (SDL_MUSTLOCK(guibg)) 
		SDL_UnlockSurface(guibg);
		
		
    // Paint Buttons
    Uint32 buttonpitch;
    Uint32 color;
    Uint32 width, height;
    for(Uint32 c = 0; c < 5; c++) {
        if(buttonMouseOver[c]) {
            blend_darkenRect((c+1) * 40, 200, 32, 32, 0xd0b0b0);
        } else {
            blend_darkenRect((c+1) * 40, 200, 32, 32, 0x909090);
        }
    	if (SDL_MUSTLOCK(buttons[c]))
	 	   if (SDL_LockSurface(buttons[c]) < 0) 
			  return;
        
        buttonpitch = buttons[c]->pitch / 4;
        width = buttons[c]->w;
        height = buttons[c]->h;
        
        
    	for(Uint32 ybg = 0; ybg < height; ybg++) { 
    		for(Uint32 xbg = 0; xbg < width; xbg++) {
    			color = ((Uint32*)buttons[c]->pixels)[xbg + ybg * buttonpitch];
    			
    			if(color != 0x0000ff00) {
    				((Uint32*)gScreen->pixels)[xbg + (c + 1) * 40 + (ybg + 200) * pitch_bg] = color;
    			}
    			
    		}
    	}

        if (SDL_MUSTLOCK(buttons[c])) 
	        SDL_UnlockSurface(buttons[c]);

    }
    
    // Paint title
    blend_darkenRect(5, 30, 300, 25, 0x808080);
    drawstring(10, 35, titles[curSnd].name, gScreen);
    
    // Paint scroller
    blend_darkenRect(0, 0, SCR_WIDTH, 25, 0xa0a0a0);
    drawstring((Sint32)scrolloffset * -1, 5, titles[curSnd].scrolltext, gScreen);
		
    // Paint status
    blend_darkenRect(7 * 40, 200, 100, 32, 0xa0a0a0);
    if(isPaused) {
        drawstring(7 * 40 + 8, 208, "Paused", gScreen);
    } else if(isPlaying) {
        drawstring(7 * 40 + 8, 208, "Playing", gScreen);
    } else {
        drawstring(7 * 40 + 8, 208, "Stopped", gScreen);
    }
    
    // --- Paint waveform ---
		// -- Background
    blend_darkenRect(40, 50, 340, 128, 0xa0a0a0);
	
		// -- Grid
	blend_darkenRect(40, 94, 340, 3, 0xa0a0a0);
	blend_darkenRect(40, 134, 340, 3, 0xa0a0a0);
	for(Uint32 offs = 0; offs < 340; offs += 68) {
		blend_darkenRect(40 + offs, 50, 3, 128, 0xa0a0a0);
	}
	blend_darkenRect(377, 50, 3, 128, 0xa0a0a0);
	blend_darkenRect(40, 50, 340, 3, 0xa0a0a0);
	blend_darkenRect(40, 175, 340, 3, 0xa0a0a0);
	
    Sint16 *curWav = (Sint16*)captureSound;
    curWav++;
    Sint16 val;
    Sint16 lastval;
    
    // find next zero point
    bool nfound = false;
    lastval = (curWav[0] >> 9);
    for(Uint32 offs = 0; offs < 1300; offs++) {
        val = (curWav[0] >> 9);
        if(val > 0 && lastval < 0) {
               nfound = true;
               break;
        }
        curWav++;
        curWav++;
    }

    
    // do the painting
    for(Uint32 offs = 0; offs < 340; offs++) {
        val = (curWav[0] >> 9) + 50 + 44;
        curWav++;
        ((Uint32*)gScreen->pixels)[offs + 40 + val * pitch_bg] = 0x00ff00;
		((Uint32*)gScreen->pixels)[offs + 40 + (val+1) * pitch_bg] = 0x00ff00;
		((Uint32*)gScreen->pixels)[offs + 40 + (val+2) * pitch_bg] = 0x00ff00;
        val = (curWav[0] >> 9) + 50 + 84;
        curWav++;
        ((Uint32*)gScreen->pixels)[offs + 40 + val * pitch_bg] = 0xff0000;
		((Uint32*)gScreen->pixels)[offs + 40 + (val+1) * pitch_bg] = 0xff0000;
		((Uint32*)gScreen->pixels)[offs + 40 + (val+2) * pitch_bg] = 0xff0000;
        //curWav++;
        //curWav++;
    }

	// Paint mouse cursor
	if(mouseShown) {
		// Do NOT show the crosshair cursor
		//drawrect(mouseX - 15, mouseY-1, 30, 3, 0x00a0a0a0);
		//drawrect(mouseX-1, mouseY - 15, 3, 30, 0x00a0a0a0);
	}

	// Unlock Surfaces if needed
	if (SDL_MUSTLOCK(gScreen)) 
		SDL_UnlockSurface(gScreen);
	
	// Tell SDL to update the whole screen
	SDL_Flip(gScreen);
		
}

void runGUI() {
	SDL_Event event;
	Sint32 x = 0;
	Sint32 y = 0;
    Sint32 i;
    gLastTick = BS_GetTicks();
	
	//SDL_ShowCursor(SDL_DISABLE);
	while(1) {
		while (SDL_PollEvent(&event)) 
		{
			switch (event.type) 
			{
				case SDL_QUIT:
					//SDL_ShowCursor(SDL_ENABLE);
					return;
				case SDL_KEYUP:
					if (event.key.keysym.sym == SDLK_q) {
						//SDL_ShowCursor(SDL_ENABLE);
						return;
					}
				case SDL_MOUSEMOTION:
					x = event.motion.x;
					y = event.motion.y;
					if(!mouseShown && x > 0 && x < SCR_WIDTH - 1 && y > 0 && y < SCR_HEIGHT - 1) {
						mouseShown = true;
						SDL_WM_GrabInput(SDL_GRAB_ON); 
					  } else if (x == 0 || x == SCR_WIDTH - 1 || y == 0 || y == SCR_HEIGHT - 1) {
						mouseShown = false;
						SDL_WM_GrabInput(SDL_GRAB_OFF);
					}

					mouseX = x;
					mouseY = y;
					break;
					
				case SDL_MOUSEBUTTONUP:
                    if(event.button.button == SDL_BUTTON_LEFT) {
                    for(i = 0; i < 5; i++) {
                        if(mouseShown && y >= 200 && x < 232 && x >= (i+1)*40 && x < (i+1)*40+32) {
                            switch(i) {
                                case 0:
                                    soundStepPrev();
                                    scrolloffset = SCR_WIDTH / 2 * -1;
                                    break;
                                case 1:
                                    soundStopMusic();
                                    break;
                                case 2:
                                    soundStartMusic();
                                    break;
                                case 3:
                                    soundPauseMusic();
                                    break;
                                case 4:
                                    soundStepNext();
                                    scrolloffset = SCR_WIDTH / 2 * -1;
                                    break;
                            }
                        }
                    }
                }
			}
			
            //blend_darkenRect((c+1) * 40, 200, 32, 32, 0xa0a0a0);
            for(i = 0; i < 5; i++) {
                if(mouseShown && y >= 200 && x < 232 && x >= (i+1)*40 && x < (i+1)*40+32) {
                    buttonMouseOver[i] = true;
                } else {
                    buttonMouseOver[i] = false;
                }
            }

		}

		
		// "Physics" engine
        Uint32 tick = BS_GetTicks();    	
    	// Delay a bit if we're too fast
    	while (tick <= gLastTick) {
    		SDL_Delay(1);
    		//sprintf(errorMessage, "TOO FAST!");
    		tick = BS_GetTicks();
    	}
    	    	
    	while (gLastTick < tick)
    	{
            // Run at virtual 100FPS
    		gLastTick += 10;
    		scrolloffset += 0.7;
    		if(scrolloffset > (double)(getstringwidth(titles[curSnd].scrolltext) + SCR_WIDTH)) {
                scrolloffset = -SCR_WIDTH;
            }
        }

		showGUI();

	}
}

