
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <math.h>

#define S_WIDTH 640
#define S_HEIGHT 480

#define KUVIENMAARA 11

#define pii 3.14

using namespace std;

void intro();
void skene1();
void skene2();
void skene3();
void skene4();
void skene5();
void skene6();
void the_end();

void draw_line(int startx, int endx, int starty, int endy);
void fade(SDL_Surface *skreen,int sx,int sy,int ex,int ey);
int offsetx, offsety;
void fadein(SDL_Surface *skreen,int sx,int sy,int ex,int ey);
void flash();
void rotozoom(SDL_Surface*, float, float, float);
void clean_screen();

void tapahtumat();
void lataas_kuvat();
void release_pics();
SDL_Surface *kuvat[KUVIENMAARA];
string ladattavat_kuvat[KUVIENMAARA] = {"pyynologo.gif","pyyno1.gif", "mystikko.gif", "blaa.gif", "prof3.jpg", "pyyno2.jpg", "metsa.jpg", "lepikkorapu.jpg", "pyyno3.jpg", "the_end.jpg", "pyyno.jpg"};

float tempor[4];
int tempora[4];

int temp;
int temp2;
int temp3;
int temp4;

int kekelol;

SDL_Surface *temp666;

SDL_Event tapahtuma;
Uint8 *nappi;

int paalla;

void (*skenet[8])() = { intro, skene1, skene2, skene3, skene4, skene5, skene6, the_end };


SDL_Surface *screen;

SDL_Rect temp_alue;

char skene;


int main(int argc, char *argv[]) 
{	
	int FPS;
	
	temp2 = 0;
	
	offsetx = 0;
	offsety = 0;
	
	paalla = 1;
	
	SDL_Init(0);
	
	screen = SDL_SetVideoMode(S_WIDTH, S_HEIGHT, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
	SDL_Delay(500);
	lataas_kuvat();
	

	skenet[0] = intro;
	skene = 0;
	
	int LOL = 0;
	
	int aika = SDL_GetTicks();
	temp3=SDL_GetTicks();
	while (paalla)
	{
		skenet[skene]();
		
		tapahtumat();
		
		
		
		SDL_Delay(1);
		
		
		/* FPS system 2 */
		
		if (LOL == 2)
		{
		SDL_Flip(screen);
		LOL = 0;
		}
		LOL++;
		
		/* FPS System
		if (LOL == 1)
		{
			LOL = 0;
			while (SDL_GetTicks() - aika < 25); 
			{
				LOL = 1;
			
				SDL_Flip(screen);
			}
		}
		else
		{
			LOL = 1;
			SDL_Flip(screen);
		}
		aika = SDL_GetTicks();
		*/
		
		cout<<SDL_GetTicks()<<"\n";
		
		if (SDL_GetTicks()>31500)
			paalla = 0;
	}
	release_pics();
	SDL_Quit();
	return 0;
}

void the_end()
{
	temp_alue.x = 50;
	temp_alue.y = 50;
	clean_screen();
	SDL_BlitSurface(kuvat[9], NULL, screen, &temp_alue);
	
	temp_alue.x = S_WIDTH-((SDL_GetTicks()-temp3)/2);
	temp_alue.y = S_HEIGHT-(sin(((SDL_GetTicks()-temp3)/2)/(S_WIDTH/3.14))*400);
	SDL_BlitSurface(kuvat[10], NULL, screen, &temp_alue);
	
}

void skene6()
{
	
}

void skene5()
{
	
	if ((SDL_GetTicks() - temp3)%2000 < 1200 || temp4 > 4 || SDL_GetTicks() < 19000)
	{

		if (temp == 2)
		{
			clean_screen();
		}
		
		
	
		temp_alue.y=(S_HEIGHT/2)-(kuvat[5]->h/2);
		
		if (temp4 < 5)
			kekelol = -(SDL_GetTicks())%207;
		temp_alue.x = -206 + kekelol;
		SDL_BlitSurface(kuvat[6], NULL, screen, &temp_alue);
		for (temp_alue.x = kekelol; temp_alue.x < S_WIDTH; temp_alue.x+=206)
		{
			SDL_BlitSurface(kuvat[6], NULL, screen, &temp_alue);
		}
	
		if (temp4 < 5 || temp2 - 100 < 200 || temp2 - 100 > 600)
		{
			temp2 = (int)((SDL_GetTicks() - (temp3)) / 10.0);
			temp_alue.x = temp2 - 200;
		}
		else
			temp_alue.x = temp2 - 200;
		temp_alue.y = (S_HEIGHT/2)-(kuvat[5]->h/2);
		
		SDL_BlitSurface(kuvat[5], NULL, screen, &temp_alue);
		
		if (temp4 < 5)
			temp = 0;
	}
	else if (temp == 0 && SDL_GetTicks() > 19000)
	{
		clean_screen();
		temp = 1;
		temp4++;
		if (temp4 == 5)
			temp3 = SDL_GetTicks() + 100;
	}
	else if (SDL_GetTicks() > 19000)
	{
		temp_alue.x = 250;
		temp_alue.y = 0;
		temp = 2;
		SDL_BlitSurface(kuvat[7], NULL, screen, &temp_alue);
	}
	
	if (SDL_GetTicks() > 27000)
	{
		temp3 = SDL_GetTicks();
		skene+=2;
	}
}

void skene4()
{
	int kekelol = SDL_GetTicks()-temp3;
	if (kekelol <= 3000)
	{
		rotozoom(kuvat[4], 4-(kekelol/1000.), 4-(kekelol/1000.), 0);
	
		temp_alue.x = (S_WIDTH/2)-(temp666->w/2);
		temp_alue.y = (S_HEIGHT/2)-(temp666->h/2);
	
		SDL_BlitSurface(temp666, NULL, screen, &temp_alue);
	}
	else
		SDL_BlitSurface(kuvat[4], NULL, screen, &temp_alue);
	
	if (kekelol > 4000)
	{
		temp_alue.x = 0;
		temp_alue.y = 0;
		temp_alue.w = S_WIDTH;
		temp_alue.h = S_HEIGHT;
		SDL_FillRect(screen, &temp_alue, 0);
		temp3 = SDL_GetTicks();
		temp2 = 0;
		cout<<"moi"<<"\n";
		skene++;
		temp = 0;
		temp4 = 2;
	}
}

void rotozoom(SDL_Surface* hailz, float zoomx, float zoomy, float angle)
{	

	if (temp666)
		SDL_FreeSurface(temp666);
	
	int sizex, sizey;
	
	int orig_x[2];
	int orig_y[2];
	int orig_l;
	if (angle == 0)
	{
		sizex = (int)(hailz->w*zoomx);
		sizey = (int)(hailz->h*zoomy);
	}
	else
	{
		
		sizex = (int)(hailz->w*zoomx);
		sizey = (int)(hailz->h*zoomy);
		
		orig_x[0] =-hailz->w/2;
		orig_x[1] =	hailz->w/2;
		
		orig_y[0] =-hailz->h/2;
		orig_y[1] =	hailz->h/2;
		
		orig_l = (int)sqrt(hailz->w*hailz->w + hailz->h*hailz->h);
	}
	
	temp666 = SDL_CreateRGBSurface(0, sizex, (sizey), hailz->format->BitsPerPixel, 0,0,0,0);
	if (angle)
	{
	}
	
	float templol = zoomx;
	float templol1 = -6;

	if (zoomx != 1 || zoomy != 1)
	{
		SDL_LockSurface( temp666 );
		for (int yy = 0; yy < hailz->h; yy++)
		{
			templol1 += zoomy;
			for (int xx = 0; xx < hailz->w; xx++)
			{
				for (int k = 0; k < templol1/(yy+1); k++)
				{
					for (int i = 0; i < templol/(xx+1); i++)
					{						
						*(Uint32 *)((Uint8 *)temp666->pixels + ((int)templol1+k) * temp666->pitch + (((int)templol+i)<< 2)) = *(Uint32 *)((Uint8 *)hailz->pixels + yy * hailz->pitch + ((xx)<< 2));
					}
				}
// 				cout<<templol1/(yy+1)<<" "<<templol1<<" "<<k<<"\n";
				templol += zoomx;
			}
			templol = zoomx;
		}
		SDL_UnlockSurface( temp666 );
	}
	else
	{
		temp_alue.x = 0;
		temp_alue.y = 0;
		SDL_BlitSurface(hailz, NULL, temp666, &temp_alue);
	}
	
	
}

void skene3()
{
	float x_temp;
	float y_temp;
	for (int x = 0; x < 80; x++)
	{
		x_temp = cos(x/80.*pii*((((SDL_GetTicks())/25)%1000)*2))*700;
		y_temp = sin(x/80.*pii*((((SDL_GetTicks())/25)%1000)*2))*700;
		draw_line(470, 200, 470+(int)x_temp, 200+(int)y_temp);
	}
	if (SDL_GetTicks() - temp3 > 1000 && SDL_GetTicks() - temp3 < 1200)
	{
		flash();
	}
	else if (SDL_GetTicks() - temp3 >= 1200)
	{
		skene++;
		temp2 = 0;
		temp3 = SDL_GetTicks();
		
		temp_alue.x = 0;
		temp_alue.y = 0;
		temp_alue.w = screen->w;
		temp_alue.h = screen->h;
	
		SDL_FillRect(screen, &temp_alue, 0);
	}
}

void flash()
{
	temp_alue.x = 0;
	temp_alue.y = 0;
	temp_alue.w = screen->w;
	temp_alue.h = screen->h;
	
	SDL_FillRect(screen, &temp_alue, 255+(255<<8)+(255<<16));
}

void draw_line(int startx, int starty, int endx, int endy) 
{
	
	int x0 = starty;
	 int x1 = endy;
	 int y0 = startx;
	 int y1 = endx;
	
	int steep;
	if (abs(y1 - y0) > abs(x1 - x0))
		steep = 1;
	else
		steep = 0;
     if (steep)
	 {
        int tep = x0;
		x0 = y0;
		y0 = tep;

		tep = x1;
		x1 = y1;
		y1 = tep;
	 }
     if (x0 > x1)
	 {
		int tep = x0;
		x0 = x1;
		x1 = tep;

		tep = y0;
		y0 = y1;
		y1 = tep;
	 }
     int deltax = x1 - x0;
     int deltay = abs(y1 - y0);
     int error = deltax / 2;
     int ystep;
     int y = y0;
     if (y0 < y1)
	 	ystep = 1;
	 else 
		 ystep = -1;
     for (int x = x0; x < x1; x++)
	 {
         if (!steep)
		 {
			 if (y < S_WIDTH && y > 0 && x <  S_HEIGHT && x > 0)
		 		*(Uint32 *)((Uint8 *)screen->pixels + x * screen->pitch + (y<< 2)) += (int)(20./sqrt((x-x0)*(x-x0)+y*y)*366666);
			 
		 }
		else
		{
			if (y < S_HEIGHT && y > 0 && x < S_WIDTH && x > 0)
				*(Uint32 *)((Uint8 *)screen->pixels + y * screen->pitch + (x<< 2)) += (int)(20./sqrt((x-x0)*(x-x0)+y*y)*366666);
		}
         error = error - deltay;
         if (error < 0)
		 {
             y = y + ystep;
             error = error + deltax;
		 }
	 }
}

void skene2()
{
	temp_alue.y = 0;
	temp_alue.x = temp2+kuvat[2]->w;
	temp_alue.y = 0;
	temp_alue.w = 100;
	temp_alue.h = kuvat[2]->h;
	SDL_FillRect(screen, &temp_alue, 0);
	temp_alue.x = temp2;
	SDL_BlitSurface(kuvat[2], NULL, screen, &temp_alue);
	
	if (SDL_GetTicks() - temp3 < 500)
	{	
		temp2 = (int)(640 - 0.7*(SDL_GetTicks() - temp3));
		
		temp_alue.x = temp2+kuvat[2]->w;
		temp_alue.y = 0;
		temp_alue.w = temp2;
		temp_alue.h = kuvat[2]->h;
	
		tempora[0] = 0;
		tempora[1] = SDL_GetTicks();
	}
	else 
	{
		if (tempora[0] > -1) // yksi
		{
			temp_alue.x = 490;
			temp_alue.y = 0;
			SDL_BlitSurface(kuvat[3], NULL, screen, &temp_alue);
			if (SDL_GetTicks() - tempora[1] > 600 && tempora[0] == 0)
			{
				tempora[0]++;
				tempora[1] = SDL_GetTicks();
				temp_alue.h = 30;
				temp_alue.w = 80;

			}
		}
		if (tempora[0] > 0) // kaksi
		{
			temp_alue.x = 334;
			temp_alue.y = 40;
			SDL_BlitSurface(kuvat[3], NULL, screen, &temp_alue);
			if (SDL_GetTicks() - tempora[1] > 600 && tempora[0] == 1)
			{
				tempora[0]++;
				tempora[1] = SDL_GetTicks();

			}
		}
		if (tempora[0] > 1) // kolme
		{
			temp_alue.x = 325;
			temp_alue.y = 1;
			SDL_BlitSurface(kuvat[3], NULL, screen, &temp_alue);
			if (SDL_GetTicks() - tempora[1] > 600 && tempora[0] == 2)
			{
				tempora[0]++;
				tempora[1] = SDL_GetTicks();

			}
		}
		if (tempora[0] > 2) // neljä
		{
			temp_alue.x = 550;
			temp_alue.y = 300;
			SDL_BlitSurface(kuvat[3], NULL, screen, &temp_alue);
			if (SDL_GetTicks() - tempora[1] > 600 && tempora[0] == 3)
			{
				temp2 = 0;
				temp3 = SDL_GetTicks();
				skene++;
			}
		}
	}
	
}

void skene1()
{
	temp = int(sin((SDL_GetTicks()/50)/10.0)*50);
	
	temp_alue.x = temp2 - 100;
	temp_alue.y = (temp)+(S_HEIGHT/2)-(kuvat[1]->h/2);
	
	SDL_BlitSurface(kuvat[1], NULL, screen, &temp_alue);
	
	temp_alue.x = temp2 - 100;
	temp_alue.y = (((temp)+(S_HEIGHT/2)-(kuvat[1]->h/2))-abs(temp))-20;
	temp_alue.w = kuvat[1]->w;
	temp_alue.h = abs(((temp)+(S_HEIGHT/2)-(kuvat[1]->h/2)) - ((temp)+(S_HEIGHT/2)-(kuvat[1]->h/2))-abs(temp))+20;
	
	SDL_FillRect(screen, &temp_alue, 0);
	
	temp_alue.x = temp2 - 100;
	temp_alue.y = (temp)+(S_HEIGHT/2)+(kuvat[1]->h/2);
	temp_alue.w = kuvat[1]->w;
	temp_alue.h = abs(temp);
	
	SDL_FillRect(screen, &temp_alue, 0);
	
	temp2 = (int)((SDL_GetTicks() - temp3) / 25.0);
	
	temp_alue.w = 0;
	temp_alue.h = 0;
	
	if ((SDL_GetTicks()-temp3) > 3500 && temp < 0 && temp > -10)
	{
		temp2 = 630;
		skene++;
		temp3=SDL_GetTicks();
	}
}

void intro()
{
	temp_alue.x = (S_WIDTH/2)-(kuvat[0]->w/2);
	temp_alue.y = (S_HEIGHT/2)-(kuvat[0]->h/2);
	
	SDL_BlitSurface(kuvat[0], NULL, screen, &temp_alue);
	
	if (SDL_GetTicks()-temp3 > 1000)
	{
		fade(kuvat[0],0,0,kuvat[0]->w,kuvat[0]->h);
	}
	if (SDL_GetTicks()-temp3 > 2500)
	{
		temp3 = SDL_GetTicks();
		skene++;
	}
}

void lataas_kuvat()
{
	for (int i = 0; i < KUVIENMAARA; i++)
	{
		kuvat[i] = IMG_Load(ladattavat_kuvat[i].c_str());
		kuvat[i] = SDL_DisplayFormat(kuvat[i]);
		
		if (i == 3 || i == 2 || i == 5 || i == 9 || i == 10)
			SDL_SetColorKey(kuvat[i], SDL_SRCCOLORKEY, SDL_MapRGB(kuvat[i]->format,0,0,0)); 
	}
}

void fadein(SDL_Surface *skreen,int sx,int sy,int ex,int ey)
{
	SDL_BlitSurface(kuvat[1], NULL, screen, &temp_alue);
}

void fade(SDL_Surface *skreen,int sx,int sy,int ex,int ey)
{
	for (int x = sx; x < ex; x+=3)
		for (int y = sy; y < ey; y+=2)
		{
			*(Uint32 *)((Uint8 *)skreen->pixels + ((y+offsetx)%skreen->h) * skreen->pitch + (((x
					+offsetx)%skreen->w)<< 2)) = 0;
			
			offsetx=((SDL_GetTicks())/100)%1000;
		}
}

void release_pics()
{
	for (int i = 0; i < KUVIENMAARA; i++)
	{
		if (kuvat[i])
			SDL_FreeSurface(kuvat[i]);
		if (screen)
			SDL_FreeSurface(screen);
	}
}

void tapahtumat()
{
	SDL_PollEvent(&tapahtuma);
	if ( tapahtuma.type == SDL_QUIT )
		paalla = false;


	nappi = SDL_GetKeyState(NULL);
	if ( nappi[SDLK_ESCAPE] )
		paalla = false;
}

void clean_screen()
{
	temp_alue.x = 0;
	temp_alue.y = 0;
	temp_alue.w = S_WIDTH;
	temp_alue.h = S_HEIGHT;
	SDL_FillRect(screen, &temp_alue, 0);
}
