/*
 * wmxmms2
 * Copyright (c)2005 Remy Bosch (remybosch@zonnet.nl)
 * 
 * This software covered by the GPL.  See COPYING file for details.
 *
 * wmxmms2.c
 *
 */
/* Standard C */
#include <stdlib.h>
#include <stdio.h>
/* X11 extentions */
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
/* XMMS@ Client */
#include <xmmsclient/xmmsclient.h>
/* graphic info */
#include "../pixmaps/wmxmms2master.xpm"
/* Give the CPU a break ;-) */
#define  USLEEP      50000

#include "wmgeneral.h"
#include "xmms2cif.h"
#include "buttons.h"
#include "options.h"

static char mask_bits[4096];
static int mask_width = 64;
static int mask_height = 64;

Display *display;
XEvent Event;

void runningLoop(void);
void showState(void);
void progressUpdate (void);
void stateChecker (void);

/**
 * The main.
 * Nothing is yet done with the arguments...
 */
int main(int argc, char *argv[])
{
	varoptions.speed=70;
	varoptions.colour="white";
	varoptions.ip_address=NULL;

	if (argc>1)
		optionHandler(argc,argv);
	
	createXBMfromXPM(mask_bits, wmxmms2master_xpm, mask_width, mask_height);
	openXwindow(argc, argv, wmxmms2master_xpm, mask_bits, mask_width, mask_height);
	initButtons();
	fontColorInit(varoptions.colour);
	drawString("OFF",4,18);
	RedrawWindow();
	STATE=S_DOWN;
	while(1){
		if (STATE==S_DOWN){
			xmms2connect();
		}else if (STATE==S_ERROR){
			disconnect_server();
			usleep(1000);
			xmms2connect();
		}else{
			runningLoop();
		}
		/*printf("Trying to (re)connect...");*/
		showState();
		while (XPending (display)) {
			XNextEvent (display, &Event);
			if (Event.type==Expose ){
				RedrawWindow ();
			}
		}
		usleep(100000);
	}
}

/**
 * If the server is up, this loop is run through.
 * If something breaks, the loop exits back in to the main where a new
 * attampt will bemade to reconnect.
 */
void runningLoop(void){
	unsigned int i=0;
	static int butnum;
	
	while(STATE!=S_ERROR && STATE!=S_DOWN){
		check_status();
		while (XPending (display)) {
			XNextEvent (display, &Event);
			switch(Event.type){
			case Expose:
				RedrawWindow ();
				break;
			case ButtonPress:
				butnum = buttonPressHandler(&Event);
				break;
			case ButtonRelease:
				buttonReleaseHandler(butnum);
				break;
			case DestroyNotify:
				XCloseDisplay(display);
				disconnect_server();
				exit(0);
			case ClientMessage:
				printf("What to do with ClientMessage?\n");
				break;
			case MotionNotify:
				break;
/*			default:
				printf("Don't know what to do with : %d\n",
						Event.type);*/
			}
		}
		if(i>(varoptions.speed/10)){
			i=0;
			progressUpdate();
			showState();
			if(STATE!=S_IDLE){
				title_info();
				playtime();
				scroller(numinfo.title_info, 4, 4);
			}
		}
		i++;
		usleep(10000);
	}
}

/**
 * Show the user what the state is other than by the buttons.
 */
void showState(void){
	static unsigned int old_state=99;
	stateUpdate(STATE);
	if(old_state!=STATE){
		switch(STATE){
		case S_DOWN:
			drawString("DOWN",4,18);
			drawString("WMXMMS2",4,4);
			break;
		case S_IDLE:
			drawString("Stopped",4,18);
			drawString("WMXMMS2",4,4);
			break;
		case S_PLAY:
			drawString("Playing",4,18);
			break;
		case S_PAUSE:
			drawString("Paused",4,18);
			break;
		case S_ERROR:
			drawString("WMXMMS2",4,4);
			drawString("ERROR!",4,18);
		}
		old_state=STATE;
		RedrawWindow();
	}
}

/**
 * As the song progressses it's nice to see where we are....
 */
void progressUpdate (void){
	static uint old_length=0;
	uint length=(uint) (56/((float) numinfo.length) * numinfo.played);
	if(length!=old_length){
		lineDraw(GREEN, 4,28, length);
	}
	old_length=length;
	RedrawWindow();
}

/**
 * For testing purposes.
 * One can keep track of the state this app is in on the console.
 */
void stateChecker (void){
		switch(STATE){
		case S_DOWN: 	printf("DOWN");		break;
		case S_IDLE:	printf("Stopped");	break;
		case S_PLAY:	printf("Playing");	break;
		case S_PAUSE:	printf("Paused");	break;
		case S_ERROR:	printf("ERROR!");}
}
