// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2008  Rammi (rammi@caff.de)
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================
package de.caff.asteroid.rammi;

import de.caff.asteroid.*;

/**
 */
public class MultiPlayerStarter
        implements PlayerStarter,
                   GameData
{
  private static class MaxAsteroidPreparer
          implements PlayerPreparer
  {
    private int nr = 4;       // starting with 5

    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (nr < MAX_NUMBER_ASTEROIDS) {
        ++nr;
        return String.format("Asteroids for multi shot: %d", nr);
      }
      else {
        return null;
      }
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setMaxAsteroidsForMultiShot(nr);
    }
  }
  private static class SmallUfoScorePreparer
          implements PlayerPreparer
  {
    private int score = -720;
    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (score == 0) {
        return null;
      }
      score /= 2;
      return "Small Ufo Score: "+score;
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setSmallUfoScore(score);
    }
  }
  private static class MinBorderPreparer
          implements PlayerPreparer
  {
    static int borderWidth = 100;
    int minBorder = 40;
    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (minBorder >= 200) {
        return null;
      }
      minBorder += 20;
      return "Minimal Border: "+minBorder;
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setMinBorder(minBorder);
      player.setMaxBorder(minBorder + borderWidth);
    }
  }
  private static class DangerFramesPreparer
          implements PlayerPreparer
  {
    private static final int[] SEQUENCE = {
      30, 45, 60, 90, 120, 150, 180
    };
    int index = -1;

    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      ++index;
      return index < SEQUENCE.length ?
              "Danger Frames: "+SEQUENCE[index]  :
              null;
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setDangerFrames(SEQUENCE[index]);
    }
  }
  private static class BlackoutFramesPreparer
          implements PlayerPreparer
  {
    int nrFrames = 0;

    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (nrFrames >= 10) {
        return null;
      }
      ++nrFrames;
      return "Blackout Frames: "+nrFrames;
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setBlackoutFrames(nrFrames);
    }
  }
  private static class MaxVolleyCountPreparer
          implements PlayerPreparer
  {
    private int count = -1;

    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (count <= 3) {
        ++count;
        return "MaxVolleyCount: "+count;
      }
      return null;
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      player.setMaxVolleyCount(count);
    }
  }
  private static class RunOncePreparer
          implements PlayerPreparer
  {
    boolean once = false;

    /**
     * Advance to next setting.
     * This is called once before the first call to {@link #prepare(de.caff.asteroid.rammi.AsteroidPlayer)}.
     *
     * @return useful settings name or <code>null</code> if there is no further setting
     */
    public String advance()
    {
      if (once) {
        return null;
      }
      once = true;
      return "Running Once";
    }

    /**
     * Prepare the player with the current setting.
     *
     * @param player player to prepare
     */
    public void prepare(AsteroidPlayer player)
    {
      // nothing
    }
  }
  /**
   * Start the player.
   * It is assumed that this method returns after starting the player.
   *
   * @param com communication access
   */
  public void startPlayer(Communication com)
  {
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new MaxAsteroidPreparer());
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new SmallUfoScorePreparer());
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new MinBorderPreparer());
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new DangerFramesPreparer());
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new BlackoutFramesPreparer());
    //MultiGamesPlayer player = new MultiGamesPlayer(com, new MaxVolleyCountPreparer());
    MultiGamesPlayer player = new MultiGamesPlayer(com, new RunOncePreparer());
    com.addFrameListener(player);
    com.addFrameListener(new LevelPauseGarbageCollector(com));
    com.addFrameListener(new HallOfFameFiller(com, "mul"));
  }
}