/********************************************************************

PhatBeat - A simple beat-counter for producers, DJs, or anybody else.
Copyright (C) 2004 Jack Chatterton <chattj AT postreal.org>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
02111-1307, USA.

*********************************************************************/

// Graphics library to use with phatbeat. Hopefully this should be 
// nice and portable, to be included with the Windows executable.

#include "SDL.h"
using namespace std;
// Added this to #define SHAREDIR
#include "phatx.h"
using namespace std;
#include "portability.h"
using namespace std;
#include <math.h>
using namespace std;

SDL_Surface *zero, *one, *two, *three, *four, *five, *six, \
	*seven, *eight, *nine, *blnk, *point;

// Load images, should be called before using either of the below
void loadNumberImages() {
	zero = portable_IMG_Load("images/0.png");
	one = portable_IMG_Load("images/1.png");
	two = portable_IMG_Load("images/2.png");
	three = portable_IMG_Load("images/3.png");
	four = portable_IMG_Load("images/4.png");
	five = portable_IMG_Load("images/5.png");
	six = portable_IMG_Load("images/6.png");
	seven = portable_IMG_Load("images/7.png");
	eight = portable_IMG_Load("images/8.png");
	nine = portable_IMG_Load("images/9.png");
	blnk = portable_IMG_Load("images/blnk.png");
	point = portable_IMG_Load("images/point.png");
}


// Routine to display a four digit number given known number sizes
// and pre-loaded number surfaces.
SDL_Surface *fourDigitNumber(float number) {
	// Digits one through four.
	int digits[4];
	
	SDL_Rect temprect;
	SDL_Surface *returnme = \
		SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA, 280, 120, \
				32, 0, 0, 0, 0);
	
	// clength is length of characteristic, mlength is length
	// of the mantissa.	
	int clength = (int)ceil(log10(number));
	if (clength < 0) 
		clength = 0;
	int mlength = 4 - clength;
	
	// Error out if we try to print something that won't fit
	// comfortably in 4 digits.
	if ((clength > 4) || (clength < -4))
		return NULL;
	
	// Set up the digits to be displayed.
	number = number * pow((float)10,(float)mlength);
	for(int i = 3; i >= 0; i--) {
		digits[3-i] = (int) floor(number / pow((float)10, (float)i));
		number -= digits[3-i] * pow((float)10, (float)i);

		// Now, fix it if the above evaluated to 10000, it should
		// actually put a one in the place and a zero in the next
		// place, so we'll change the counters accordingly.
		if (digits[3-i] == 10) {
			digits[3-i] = 1;
			mlength--;
			clength++;
		}
	}
	
	// sHIFT number right as needed to discard rightmost zeros
	// We will use -1 as a token to represent a blank space.
	for(int i = 0; i < mlength; i++)
		if (digits[3] == 0) {
			digits[3] = digits[2];
			digits[2] = digits[1];
			digits[1] = digits[0];
			digits[0] = -1;
			// Inc clength so that the decimal will be in the right
			// place when added below.
			clength++;
		}
	
	// Place numbers on blank returnme part.
	temprect.y = 0;
	for(int i=0; i <= 3; i++) {
		temprect.x = 70 * i;
		switch(digits[i]) {
			case 0: SDL_BlitSurface(zero, NULL, returnme, &temprect);
				break;
			case 1: SDL_BlitSurface(one, NULL, returnme, &temprect);
				break;
			case 2: SDL_BlitSurface(two, NULL, returnme, &temprect);
				break;
			case 3: SDL_BlitSurface(three, NULL, returnme, &temprect);
				break;
			case 4: SDL_BlitSurface(four, NULL, returnme, &temprect);
				break;
			case 5: SDL_BlitSurface(five, NULL, returnme, &temprect);
				break;
			case 6:	SDL_BlitSurface(six, NULL, returnme, &temprect);
				break;
			case 7:	SDL_BlitSurface(seven, NULL, returnme, &temprect);
				break;
			case 8:	SDL_BlitSurface(eight, NULL, returnme, &temprect);
				break;
			case 9:	SDL_BlitSurface(nine, NULL, returnme, &temprect);
				break;
			case -1: 
			default:	
				SDL_BlitSurface(blnk, NULL, returnme, &temprect);
		}
	}
	
	// Place decimal point where appropriate.
	// Notice that a 4 digit characteristic number does not get
	// a decimal point. 
	if (clength == 4)
		return returnme;
	
	temprect.x = 70 * clength; temprect.y = 0;
	SDL_BlitSurface(point, NULL, returnme, &temprect);
	
	return returnme;
}

// Wrapper for fourDigitNumber that shaves off the first two digits.
// Inefficient as hell, but more elegant than writing another
// 100 lines of image manipulation ...
SDL_Surface *twoDigitInteger(int number) {
	SDL_Surface *returnme = SDL_CreateRGBSurface(SDL_HWSURFACE|SDL_SRCALPHA, 140, 120, 32, 0, 0, 0, 0);
	SDL_Surface *bignum = fourDigitNumber(number);
	SDL_Rect temprect;

	temprect.x = 140; temprect.y = 0;
	temprect.w = 140; temprect.h = 120;
	SDL_BlitSurface(bignum, &temprect, returnme, NULL);

	return returnme;
}
