/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * main.cc
 * Copyright (C) Frederik Mutzel 2009 <crazywater@>
 * 
 * main.cc 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 3 of the License, or
 * (at your option) any later version.
 * 
 * main.cc 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, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h" 

#define WIDTH 640
#define HEIGHT 480
#define INFOBARHEIGHT 60
#define PLAYER "Resources/player.png"
#define BACKGROUND "Resources/background.png"
#define FONT "Resources/FreeSans.ttf"
#define FONTSIZE 32
#define TITLE "potcat."

SDL_Surface *screen, *plimage, *bgimage;
SDL_Event event;
SDL_Rect dest;
TTF_Font* font;

int xpos, ypos, xvel, yvel, bgcolor, bgpos = 0;
long long unsigned int points;
bool left_pressed, right_pressed, up_pressed, down_pressed;

void StartMovement(SDL_KeyboardEvent *key)
{
	switch(key->keysym.sym){
		case SDLK_LEFT:
			left_pressed = true;
			break;
		case SDLK_RIGHT:
			right_pressed = true;
			break;
		case SDLK_UP:
			up_pressed = true;
			break;
		case SDLK_DOWN:
			down_pressed = true;
			break;
	}
}

void StopMovement(SDL_KeyboardEvent *key)
{
	switch(key->keysym.sym){
		case SDLK_LEFT:
			left_pressed = false;
			xvel = 0;
			break;
		case SDLK_RIGHT:
			right_pressed = false;
			xvel = 0;
			break;
		case SDLK_UP:
			up_pressed = false;
			break;
		case SDLK_DOWN:
			down_pressed = false;
			break;
	}
}

void Move()
{
	bool onthefloor = ypos + plimage->h >= HEIGHT;
	// Gravity
	if (!onthefloor) yvel += 2;
	else yvel = 0;
	
	// Jump
	if (up_pressed) 
	{
		if(onthefloor) yvel -= 25;
		else yvel -= 1;
	}
	

	if (down_pressed) yvel += 1;
	if (right_pressed) xvel += 1;
	if (left_pressed) xvel -= 1;
	
	// X-axis: checking for scrolling
	// Right border
	int rboundary = (int) 7 * WIDTH / 8 - plimage->w;
	int lboundary = (int) WIDTH / 8;
	int maxbgpos = bgimage->w - WIDTH;
	if (xpos >= rboundary && xvel > 0 && bgpos < maxbgpos)
	{
		xpos = rboundary;
		bgpos += xvel;
		if (bgpos > maxbgpos) {
			bgpos = maxbgpos;
		}
	}
	// Left border
	else if (xpos <= lboundary && xvel < 0 && bgpos > 0)
	{
		xpos = lboundary;
		bgpos += xvel;
		if (bgpos < 0) {
			bgpos = 0;
		}
	}
	// No border touched
	else
	{
		int maxxpos = WIDTH - plimage->w;
		xpos += xvel;
		if (xpos > maxxpos) xpos = maxxpos;
		if (xpos < 0) xpos = 0;
	}
		
	ypos += yvel;
	
	// Y-axis: collision checking
	if (ypos < INFOBARHEIGHT) ypos = INFOBARHEIGHT;
	if (ypos > (HEIGHT - plimage->h)) ypos = HEIGHT - plimage->h;
}

void RedrawPanel()
{
	char pointstring[1024];
    SDL_Surface *resulting_text;
	
	sprintf(pointstring, "%llu", points);
	SDL_Color fontcolor = {0,0,0,255};
	
	resulting_text = TTF_RenderText_Blended(font, pointstring, fontcolor);
	
	dest.x = WIDTH - resulting_text->w - 10;
	dest.y = 10;
	dest.w = 400;
	dest.h = 50;
	
	SDL_BlitSurface(resulting_text, NULL, screen, &dest);
	SDL_FreeSurface(resulting_text);
}

void RedrawBackground()
{
	dest.x = bgpos;
	dest.y = 0;
	dest.w = WIDTH;
	dest.h = HEIGHT;
	
	SDL_BlitSurface(bgimage, &dest, screen, NULL);
}
void RedrawPlayer()
{
	dest.x = xpos;
	dest.y = ypos;
	dest.w = plimage->w;
	dest.h = plimage->h;
	
	SDL_BlitSurface(plimage, NULL, screen, &dest);
}

void Redraw()
{
	RedrawBackground();
	RedrawPlayer();
	RedrawPanel();
	SDL_Flip(screen);
}

SDL_Surface* LoadImage(const char file[256])
{
	SDL_Surface *temp, *image;
	temp = IMG_Load(file);
	if (temp == NULL) {
		printf("Unable to load image: %s\n", SDL_GetError());
		return NULL;
	}
	image = SDL_DisplayFormatAlpha(temp);
	SDL_FreeSurface(temp);
	return image;
}

bool Initialize()
{
	printf("Initializing SDL.\n");
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
		return false;
	}
	
	printf("Initializing window.\n");
	screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, SDL_ANYFORMAT);
	if (screen == NULL) {
		fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
		return false;
	}
	SDL_WM_SetCaption(TITLE, TITLE);
	
	printf("Loading images.\n");	
	plimage = LoadImage(PLAYER);
	bgimage = LoadImage(BACKGROUND);
	
	printf("Initializing fonts.\n");
	if (TTF_Init() != 0) 
	{
		printf("Unable to initialize SDL_ttf: %s \n", TTF_GetError());
		return false;
	}

	font = TTF_OpenFont(FONT, FONTSIZE);
	if (font == NULL){
		printf("Unable to load font: %s %s \n", FONT, TTF_GetError());
		return false;
	}
	
	xpos = 0;
	ypos = HEIGHT - plimage->h;
	
	Redraw();
	return true;
}

void UpdatePoints()
{
	points++;
}

int main()
{
	bool running = true;
	if(Initialize()) {
		while(running) {
			while(SDL_PollEvent(&event)) {
				switch(event.type) {
					case SDL_KEYDOWN:
						StartMovement(&event.key);
						break;
					case SDL_KEYUP:
						StopMovement(&event.key);
						break;
					case SDL_QUIT:
						running = false;
						break;
				}
			}
			Move();
			UpdatePoints();
			Redraw();
			SDL_Delay(30);
		}
	}
	
}