/*


    Evolute version 0.7
    Copyright (C) 2010 Antti Vainio

    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 3 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, see <http://www.gnu.org/licenses/>.


*/

//          funktioita.cpp

#ifdef _WIN32
       #include <windows.h>
#endif
#include <string.h>
#include <math.h>
#include "global.hpp"

//näyttää virheen messageboxilla
void naytavirhe(const char *teksti) {
     char teksti2[110];
     sprintf(teksti2, " ERROR: %s", teksti);
     log(teksti2);
     #ifdef _WIN32
            MessageBox(NULL, teksti, "Error", MB_ICONHAND);
     #endif
}

//kirjoittaa logiin
void log(const char *teksti) {
     printf("%s\n", teksti);
     #ifndef _WIN32
            if(logtiedosto != NULL) fprintf(logtiedosto, "%s\n", teksti);
     #endif
}

//asettaa pelattavan kartan
void asetakartta(const char *teksti) {
     sprintf(nykyinenkartta, teksti);
}

//avaa karttatiedoston - palauttaa false, jos epäonnistui
//etsii tiedostoja maps/Stages, maps/Survival ja maps kansioista
//HUOM! kun tänne lisää uusia sijainteja, täytyy ne lisätä myös tämän jälkeen tulevaan funktioon ja newhiscore.cpp:ssä majailevaan luouusihiscore() funktioon
bool avaakartta() {
     char tiedostopolku[40];
     
     sprintf(tiedostopolku, "maps/Tutorial/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) return true;
     
     sprintf(tiedostopolku, "maps/Stages/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) return true;
     
     sprintf(tiedostopolku, "maps/Survival/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) return true;
     
     sprintf(tiedostopolku, "maps/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) return true;
     
     //ei löytynyt
     sprintf(viesti, "Couldn't find map file '%s.txt'", nykyinenkartta);
     naytavirhe(viesti);
     return false;
}

//avataan hiscoretiedosto
//avataan r+:lla, jotta voitaisiin myös tallentaa uusi hiscore
bool avaahiscore() {
     char tiedostopolku[50];
     
     sprintf(tiedostopolku, "maps/Survival/%s_hiscores.dat", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r+");
     if(tiedosto != NULL) return true;
     
     sprintf(tiedostopolku, "maps/%s_hiscores.dat", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r+");
     if(tiedosto != NULL) return true;
     
     //ei löytynyt
     return false;
}

//avataan tyhjä hiscoretiedosto kirjoittamista varten
bool avaahiscorew() {
     char tiedostopolku[50];
     
     sprintf(tiedostopolku, "maps/Survival/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) {
                 fclose(tiedosto);
                 sprintf(tiedostopolku, "maps/Survival/%s_hiscores.dat", nykyinenkartta);
                 tiedosto = fopen(tiedostopolku, "w");
                 return true;
     }
     sprintf(tiedostopolku, "maps/%s.txt", nykyinenkartta);
     tiedosto = fopen(tiedostopolku, "r");
     if(tiedosto != NULL) {
                 fclose(tiedosto);
                 sprintf(tiedostopolku, "maps/%s_hiscores.dat", nykyinenkartta);
                 tiedosto = fopen(tiedostopolku, "w");
                 return true;
     }
     
     //ei löytynyt
     sprintf(viesti, "Couldn't find %s map or create 'hiscores.dat' file for it", nykyinenkartta);
     naytavirhe(viesti);
     return false;
}

//luo uuden hiscore tiedosto, jos vanha on hävyksissä
//pyritään luomaan samaan kansioon, missä vastaava karttatiedosto majailee
void luouusihiscoref() {
     if(avaahiscorew()) {
          for(int i=10;i>0;i--) fprintf(tiedosto, "-\n%i\n", i * 10000);
          fclose(tiedosto);
          sprintf(viesti, "Created new 'hiscores.dat' file for %s", nykyinenkartta);
          log(viesti);
     }
}

//luo uuden progress tiedoston
//kohta kertoo kuinka monta Stagea on jo läpäisty
void luoprogressf(const short kohta) {
     tiedosto = fopen("maps/Stages/progress.dat", "w");
     for(int i=0;i<10;i++) {
             if(i < kohta) fprintf(tiedosto, "1");
             else fprintf(tiedosto, "0");
     }
     fclose(tiedosto);
     sprintf(viesti, "Created new 'progress.dat' file with %i stages completed", kohta);
     log(viesti);
}

//hoitaa SDL tapahtumat
//palauttaa true, jos käyttäjä painoi ruksia
bool hoidatapahtumat() {
     SDL_Event tapahtuma;
     while (SDL_PollEvent(&tapahtuma)) {
           switch (tapahtuma.type) {
                  case SDL_QUIT:
                  #ifdef _WIN32
                  if(MessageBox(NULL, "Really quit?", "", MB_YESNO) == IDYES) {
                  #endif
                               menuvalinta = -1;
                               kokonaanpois = true;
                  #ifdef _WIN32
                  }
                  #endif
                  break;
                  default: break;
           }
     }
     if(kokonaanpois) return true;
     else return false;
}

//laskee fps:n keskiarvon kymmeneltä framelta ja odottaa tarvittavan ajan
void laskefps() {
     fpslaskuri++;
     fpssumma+= frame; //lasketaan framejen pituudet yhteen
     
     //piirretään PFS vain joka kahdeskymmenes frame
     if(fpslaskuri == 20) {
                  if(fpssumma != 0)  fps = int(round(20000 / fpssumma)); //mukana keskiarvon lasku, ilman keskiarvoa: 1000/fpssumma
                  if(fps > 999) fps = 999;
                  fpslaskuri = 0;
                  fpssumma = 0;
     }
     
     //lasketaan kulunut aika
     loppuaika = SDL_GetTicks();
     frame = loppuaika - alkuaika;
     
     //odotetaan
     if(frame < framerate) SDL_Delay(framerate - frame);
}

//laskee kulman
float laskekulma(const float alkux, const float alkuy, const float loppux, const float loppuy) {
     float palautuskulma;
      
     //lasketaan suunta radiaaneina
     if(alkux == loppux) {
              if(alkuy >= loppuy) palautuskulma = PI / 2.0;
              else palautuskulma = PI * 3.0 / 2.0;
     }
     else {
          float palautuskulmakerroin = (alkuy - loppuy)/(loppux - alkux);
          if(alkux < loppux) palautuskulma = atan(palautuskulmakerroin);
          else palautuskulma = atan(palautuskulmakerroin) + PI;
          if(palautuskulma < 0) palautuskulma = palautuskulma + 2 * PI;
     }
     return palautuskulma;
}

//laskee etäisyyden
float laskeetaisyys(const float alkux, const float alkuy, const float loppux, const float loppuy) {
     return sqrt((alkux - loppux) * (alkux - loppux) + (alkuy - loppuy) * (alkuy - loppuy));
}
