// ============================================================================
// 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.*;
import de.caff.util.Tools;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.File;

/**
 *   Display pixel reached by a shoot.
 */
public class ShootingLaneDisplay
        implements GameData,
                   DrawableProvider
{
  private BulletLifetimeInformation bulletInfo;
  private BufferedImage[] images = new BufferedImage[256];

  /**
   * Constructor.
   * @param laneColor color used for lane colorizing
   */
  public ShootingLaneDisplay(Color laneColor)
  {
    this(laneColor, laneColor);
  }

  public ShootingLaneDisplay(Color laneColorEven, Color laneColorOdd)
  {
    try {
      bulletInfo = BulletLifetimeInformation.getLifetimeInformation(8, 1);
    } catch (IOException e) {
      e.printStackTrace();
    }
    laneColorEven = laneColorEven.getAlpha() < 256 ? laneColorEven : new Color(laneColorEven.getRed(),
                                                                   laneColorEven.getGreen(),
                                                                   laneColorEven.getBlue(),
                                                                   0x80);
    laneColorOdd  = laneColorOdd.getAlpha() < 256 ? laneColorOdd : new Color(laneColorOdd.getRed(),
                                                                   laneColorOdd.getGreen(),
                                                                   laneColorOdd.getBlue(),
                                                                   0x80);
    for (int i = 0;  i < 256;  ++i) {
      images[i] = new BufferedImage(EXTENT_X, EXTENT_Y, BufferedImage.TYPE_INT_ARGB);
      fillImage(bulletInfo, images[i], (byte)i, laneColorEven, laneColorOdd);
    }
  }

  private static void fillImage(BulletLifetimeInformation bulletInfo,
                                BufferedImage image,
                                byte dirByte,
                                Color laneColorEven,
                                Color laneColorOdd)
  {

    if (bulletInfo != null) {
      int rgbEven = laneColorEven.getRGB();
      int rgbOdd  = laneColorOdd.getRGB();
      for (int x = 0;  x < EXTENT_X;  ++x) {
        for (int y = 0;  y < EXTENT_Y;  ++y) {
          BulletLifetimeInformation.BulletFrameInfo[] bulletInfos = bulletInfo.getHitBulletInfos(x - EXTENT_X/2,
                                                                                                 EXTENT_Y/2 - y);
          int rgb = 0;
          for (BulletLifetimeInformation.BulletFrameInfo info: bulletInfos) {
            if (info.getDirection() == dirByte) {
              rgb = (info.getFrame() % 2 == 0) ? rgbEven : rgbOdd;
              break;
            }
          }
          image.setRGB(x, y, rgb);
        }
      }
    }
  }

  private static void fillImageHitable(BulletLifetimeInformation bulletInfo,
                                       BufferedImage image,
                                       Color laneColor)
  {
    if (bulletInfo != null) {
      int rgb = laneColor.getRGB();
      for (int x = 0;  x < EXTENT_X;  ++x) {
        for (int y = 0;  y < EXTENT_Y;  ++y) {
          BulletLifetimeInformation.BulletFrameInfo[] bulletInfos = bulletInfo.getHitBulletInfos(x - EXTENT_X/2,
                                                                                                EXTENT_Y/2 - y);
          image.setRGB(x, y, bulletInfos.length > 0 ? rgb : 0);
        }
      }
    }
  }

  /**
   * Draw information of a frame.
   *
   * @param g     graphics context
   * @param frame frame information
   */
  public void draw(Graphics2D g, FrameInfo frame)
  {
    BufferedImage image = images[Tools.byteToUnsigned(frame.getShootingDirectionLowLevel())];
    g.drawImage(image, 0, 0, null);
  }

  private static void saveImage(RenderedImage image, String id) throws IOException
  {
    String name = String.format("shootlane-%s.png", id);
    System.out.println("Saving "+name+" ...");
    ImageIO.write(image, "PNG", new File(name));
    System.out.println("Done.");
  }

  public static void main(String[] args) throws IOException
  {
    BulletLifetimeInformation bulletInfo = BulletLifetimeInformation.getLifetimeInformation(8, 2);
    BufferedImage image  = new BufferedImage(EXTENT_X, EXTENT_Y, BufferedImage.TYPE_INT_ARGB);
    if (args.length == 0) {
      fillImageHitable(bulletInfo, image, Color.red);
      saveImage(image, "HITABLE");
      for (int i = 0;  i < 256;  ++i) {
        fillImage(bulletInfo, image, (byte)i, Color.red, Color.blue);
        saveImage(image, String.format("%03d", i));
      }
    }
    else {
      for (String arg: args) {
        if ("HIT".equalsIgnoreCase(arg)) {
          fillImageHitable(bulletInfo, image, Color.red);
          saveImage(image, "HITABLE");
        }
        else {
          int id = Integer.parseInt(arg);
          fillImage(bulletInfo, image, (byte)id, Color.red, Color.blue);
          saveImage(image, String.format("%03d", id));
        }
      }
    }
  }
}
