// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2008  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================
package de.caff.asteroid;

import java.awt.*;
import java.util.Collection;

/**
 * Bullet object in automated player of Asteroids game.
 *
 * Bullets are either shot by the player's ship or by an ufo.
 *
 * This class is part of a solution for a
 * <a href="http://www.heise.de/ct/creativ/08/02/details/">competition by the German computer magazine c't</a>.
 */
public class Bullet
        extends MovingGameObject
{
  /** Minimal lifetime of a bullet. */
  public static final int MIN_LIFETIME = 69;
  /** Maximal lifetime of a bullet. */
  public static final int MAX_LIFETIME = 72;
  /** Usual Bullet speed. */
  public static final int BULLET_SPEED = 8;
  /** Size of bullet. */
  public static final int BULLET_SIZE = 3;
  /** Size for picking. */
  private static final int PICK_SIZE = 3;
  /** Halo colors. */
  private static final Color[] HALO_COLORS = new Color[] {
          Color.white,
          Color.white,
          new Color(0xf0, 0xf0, 0xf0),
          new Color(0xc0, 0xc0, 0xc0),
          new Color(0x80, 0x80, 0x80),
          new Color(0x40, 0x40, 0x40),
  };
  /** Index of the asteroid in datagram. */
  private final int index;
  /** Was this a ship bullet or a ufo bullet? (<code>true</code>: by ship, <code>false</code>: by ufo, <code>null</code>: unknown. */
  private Boolean friendly;

  /**
   *  Constructor.
   *  @param index index of bullet in datagram
   *  @param x  x coordinate
   *  @param y  y coordinate
   */
  public Bullet(int index, int x, int y)
  {
    super(x, y);
    this.index = index;
  }

  /**
   *  Get the size of the object.
   *
   *  The size returned by this method is half the side length of a square which contains the object,
   *  so the object's bounding box is between (x - size, y - size) and (x + size, y + size).
   *  @return object size
   */
  public int getSize()
  {
    return BULLET_SIZE;
  }

  /**
   *  Get the index of this bullet in the datagram.
   *  @return index in datagram
   */
  public int getIndex()
  {
    return index;
  }

  /**
   *  Draw the object.
   *  @param g graphics context
   */
  public void draw(Graphics2D g)
  {
    drawVelocityVector(g, Color.blue);

    Color lastColor = null;
    for (int i = HALO_COLORS.length - 1;  i >= 0;  --i) {
      Color color = HALO_COLORS[i];
      if (!color.equals(lastColor)) {
        g.setColor(color);
        g.fillOval(getX()-i, getY()-i, 2*i+1, 2*i+1);
        lastColor = color;
      }
    }
  }

  /**
   * Get the properties of this object.
   *
   * @return collection of properties
   */
  @Override
  public Collection<Property> getProperties()
  {
    Collection<Property> props = super.getProperties();
    props.add(new Property<Integer>("Lifetime", getLifetime()));
    return props;
  }

  /**
   * Get the type of game object.
   *
   * @return game object type
   */
  public String getObjectType()
  {
    return "Bullet";
  }

  /**
   * Returns a string representation of the object.
   *
   * @return a string representation of the object.
   */
  @Override
  public String toString()
  {
    return String.format("Bullet@(%d,%d)", getX(), getY());
  }

  /**
   * Get the bounding box of this rectangle.
   *
   * @return the bounding box
   */
  @Override
  public Rectangle getBounds()
  {
    return new Rectangle(getX()-1, getY()-1, 2, 2);
  }

  /**
   * Get bounds for picking operations.
   *
   * @return picking bounds
   */
  @Override
  public Rectangle getPickBounds()
  {
    return new Rectangle(getX()-PICK_SIZE, getY()-PICK_SIZE, 2*PICK_SIZE, 2*PICK_SIZE);
  }

  /**
   * Access method for visitor pattern.
   *
   * @param visitor visitor
   */
  public void visitedBy(GameObjectVisitor visitor)
  {
    visitor.handle(this);
  }

  /**
   *  Is this a friendly bullet?
   *  @return <code>Boolean.TRUE</code>: friendly bullet fired by ship<br>
   *          <code>Boolean.FALSE</code>: unfriendly bullet fired by ufo<br>
   *          <code>null</code>: unknown
   */
  public Boolean isFriendly()
  {
    return friendly;
  }

  /**
   *  Set whether this bullet was friendly.
   *  @param friendly <code>true</code>: friendly bullet fired by ship<br<
   *                  <code>false</code>: unfriendly bullet fired by ufo
   */
  public void setFriendly(boolean friendly)
  {
    this.friendly = friendly;
  }

  /**
   * Inheret properties from another game object.
   * This basic implementation sets the identity to the same value as
   * the one of the other object.
   *
   * @param obj other object, probably of previous frame
   */
  @Override
  public void inheret(MovingGameObject obj)
  {
    super.inheret(obj);
    friendly = ((Bullet)obj).friendly;
  }
}
