
/*
 * XKOBO, a video-oriented game
 * Copyright (C) 1995  Akira Higuchi
 *     a-higuti@math.hokudai.ac.jp
 * 
 * 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.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "xkobo.h"
#include "screen.h"
#include "manage.h"
#include "scenes.h"
#include "score.h"
#include "enemies.h"
#include "myship.h"
#include "radar.h"
#include "key.h"

_manage_state   _manage::state;
bool            _manage::next_state_out;
bool            _manage::next_state_next;
int             _manage::highscore = 0;
int             _manage::last_scene = 0;
int             _manage::scene_num;
int             _manage::ships;
int             _manage::level;
int             _manage::count;
int             _manage::score;
int             _manage::score_changed;
int             _manage::delay_count;
int             _manage::rest_cores;
int             _manage::return_value = 0;

void _manage::play_start(int start_scene)
{
    ships = 5;
    level = 0;
    score = 0;
    scene_num = start_scene - 1;
    _manage::next_scene();
    _manage::init_resources();
}

void _manage::next_scene()
{
    scene_num++;
    screen.init_scene(scene_num);
}

void _manage::retry()
{
    ships--;
    if (ships <= 0){
        last_scene = scene_num;
        if (highscore < score) highscore = score;
        scorefile.record(highscore, last_scene);
        ships = 0;
        state = title;
        screen.init_scene(-1);
        screen.prepare();
        return;
    }
}

void _manage::init_resources()
{
    state = playing;
    count = 0;
    delay_count = 0;
    score_changed = 0;
    next_state_out = false;
    next_state_next = false;
    
    key.init();
    enemies.init();
    myship.init();
    rest_cores = screen.prepare();
    screen.generate_fixed_enemies();
    _manage::put_info();
}

void _manage::put_info()
{
    static char s[1024];
    const int posx = WIN_SIZEY+2;
    
    wbase.string(posx, 20, "SCORE");
    sprintf(s, "%09d", score);
    wbase.string(posx, 35, s);
    
    wbase.string(posx, 50, "STAGE");
    sprintf(s, "%09d", scene_num + 1);
    wbase.string(posx, 65, s);
    
    wbase.string(posx, 80, "SHIPS");
    sprintf(s, "%09d", ships);
    wbase.string(posx, 95, s);
}

void _manage::put_score()
{
    static char s[1024];
    const int posx = WIN_SIZEY+2;
    
    sprintf(s, "%09d", score);
    wbase.string(posx, 35, s);
    score_changed = 0;
}

void _manage::eventloop()
{
    while (win::xcheckevent()){
        wbase.eventloop();
        wchip.eventloop();
        wradar.eventloop();
        wscore.eventloop();
    }
}

/****************************************************************************/
void _manage::init()
{
    scorefile.init(&highscore, &last_scene);
    screen.init();
    screen.init_scene(-1);
    screen.prepare();
    _manage::put_info();
    count = 0;
    ships = 5;
    level = 0;
    state = title;
    delay_count = 0;
}

int _manage::mainloop()
{
    _manage::eventloop();
    if (state != playing){
        return return_value;
    }
    
    count++;
    
    if (delay_count) delay_count--;
    if (delay_count == 1){
        if (enemies.exist_pipe()){
            delay_count = 2;
        }
        else {
            if (next_state_out == true){
                _manage::retry();
                if (ships <= 0){
                    _manage::put_info();
                    return return_value;
                }
            }
            if (next_state_next == true){
                _manage::next_scene();
            }
            _manage::put_info();
            _manage::init_resources();
            return return_value;
        }
    }
    
    myship.move();
    enemies.move();
    myship.hit_structure();
    
    myship.put();
    enemies.put();
    if (score_changed) _manage::put_score();
    radar.trace_myship();
    wchip.set_position(myship.get_virtx(),myship.get_virty());
    win::xflush();
    win::xsync();
    wchip.restore();
    
    return return_value;
}

void _manage::lost_myship()
{
    if (delay_count == 0)
      delay_count = 20;
    next_state_out = true;
}

void _manage::destroyed_a_core()
{
    rest_cores--;
    if (rest_cores == 0){
        next_state_next = true;
        delay_count = 50;
    }
    screen.generate_fixed_enemies();
}

void _manage::start_button()
{
    switch (state){
      case title:{
          wbase.warp_pointer(WIN_SIZEX-5, WIN_SIZEY-5);
          _manage::play_start();
          break;
      }
      case paused:{
          wbase.warp_pointer(WIN_SIZEX-5, WIN_SIZEY-5);
          state = playing;
          break;
      }
      case playing:{
          wbase.warp_pointer(          4,           4);
          state = paused;
          wchip.back();
          break;
      }
    }
}

void _manage::cont_button()
{
    if (state == title){
        wbase.warp_pointer(WIN_SIZEX-5, WIN_SIZEY-5);
        _manage::play_start(last_scene);
    }
}

void _manage::exit_button()
{
    if (state == title){
        return_value = 1;
        /*exit(0);*/
    }
    ships = 0;
    _manage::retry();
    _manage::put_info();
}
    

void _manage::add_score(int sc)
{
    score += sc;
    score_changed = 1;
}

void _manage::get_highscore(char *s)
{
    sprintf(s, "high score : %09d", highscore);
}    
