package au.com.codeka.warworlds.game.starfield;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

import org.andengine.opengl.texture.atlas.bitmap.source.IBitmapTextureAtlasSource;
import org.andengine.opengl.texture.atlas.source.BaseTextureAtlasSource;

import au.com.codeka.common.model.BaseColony;
import au.com.codeka.common.model.BaseStar;
import au.com.codeka.warworlds.model.Empire;
import au.com.codeka.warworlds.model.EmpireManager;
import au.com.codeka.warworlds.model.EmpireShieldManager;
import au.com.codeka.warworlds.model.Sector;
import au.com.codeka.warworlds.model.SectorManager;
import au.com.codeka.warworlds.model.Star;

/**
 * An {@link IBitmapTextureAtlasSource} that returns a bitmap to use as a texture for the tactical
 * sprite that covers a sector.
 */
public class TacticalBitmapTextureSource extends BaseTextureAtlasSource
    implements IBitmapTextureAtlasSource {

  // The size of the texture, in pixels, that we'll generate.
  private static final int TEXTURE_SIZE = 128;

  // The radius of the circle, in pixels, that we'll put around each empire.
  private static final int CIRCLE_RADIUS = 20;

  private Sector sector;
  private Bitmap bitmap;

  public static TacticalBitmapTextureSource create(Sector sector) {
    return new TacticalBitmapTextureSource(sector);
  }

  private TacticalBitmapTextureSource(Sector sector) {
    this(sector, null);
  }

  private TacticalBitmapTextureSource(Sector sector, Bitmap bitmap) {
    super(0, 0, TEXTURE_SIZE, TEXTURE_SIZE);
    this.sector = sector;
    this.bitmap = bitmap;
  }

  @Override
  public IBitmapTextureAtlasSource deepCopy() {
    return new TacticalBitmapTextureSource(sector, bitmap);
  }

  @Override
  public Bitmap onLoadBitmap(Bitmap.Config config) {
    return onLoadBitmap(config, false);
  }

  @Override
  public Bitmap onLoadBitmap(Bitmap.Config config, boolean mutable) {
    if (bitmap == null || bitmap.isRecycled()) {
      // NOTE: This assumes the config never changes, is that OK?
      bitmap = createBitmap(config);
    }
    return bitmap;
  }

  private Bitmap createBitmap(Bitmap.Config config) {
    Bitmap bmp = Bitmap.createBitmap(TEXTURE_SIZE, TEXTURE_SIZE, config);
    Canvas canvas = new Canvas(bmp);

    Paint paint = new Paint();
    paint.setStyle(Paint.Style.FILL);

    // We have to look at sectors around this one as well, so that edges look right
    for (int offsetY = -1; offsetY <= 1; offsetY++) {
      for (int offsetX = -1; offsetX <= 1; offsetX++) {
        Sector s;
        if (offsetX == 0 && offsetY == 0) {
          s = sector;
        } else {
          s = SectorManager.i.getSector(sector.getX() + offsetX, sector.getY() + offsetY);
        }
        if (s == null) {
          continue;
        }

        drawCircles(s, offsetX, offsetY, canvas, paint);
      }
    }

    return bmp;
  }

  private void drawCircles(Sector sector, int offsetX, int offsetY, Canvas canvas, Paint paint) {
    float scaleFactor = (float) TEXTURE_SIZE / Sector.SECTOR_SIZE;

    for (BaseStar baseStar : sector.getStars()) {
      float x = (baseStar.getOffsetX() + offsetX * Sector.SECTOR_SIZE) * scaleFactor;
      float y = (baseStar.getOffsetY() + offsetY * Sector.SECTOR_SIZE) * scaleFactor;
      float radius = CIRCLE_RADIUS;

      if (x < -radius || x > TEXTURE_SIZE + radius || y < -radius || y > TEXTURE_SIZE + radius) {
        // if it's completely off the bitmap, skip drawing it
        continue;
      }

      Empire empire = getEmpire((Star) baseStar);
      if (empire == null) {
        continue;
      }
      paint.setColor(EmpireShieldManager.i.getShieldColour(empire));

      canvas.drawCircle(x, y, radius, paint);
    }
  }

  private static Empire getEmpire(Star star) {
    // if it's a wormhole, the empire is the owner of the wormhole
    BaseStar.WormholeExtra wormholeExtra = star.getWormholeExtra();
    if (wormholeExtra != null) {
      return EmpireManager.i.getEmpire(wormholeExtra.getEmpireID());
    }

    // otherwise, pick the first colony we find to represent the star
    // TODO: what if the star is colonized by more than one empire?
    for (BaseColony colony : star.getColonies()) {
      if (colony.getEmpireKey() != null) {
        return EmpireManager.i.getEmpire(Integer.parseInt(colony.getEmpireKey()));
      }
    }

    return null;
  }
}

@@ -341,16 +341,61 @@
 Colony;%0A
+import au.com.codeka.common.model.BaseFleet;%0A
 import a
@@ -3536,24 +3536,45 @@
 e;%0A      %7D%0A%0A
+      int color = 0;%0A
       Empire
@@ -3651,47 +3651,228 @@
     
-continue;
+empire = getFleetOnlyEmpire((Star) baseStar);%0A        if (empire != null) %7B
 %0A      
-%7D%0A
     
-  paint.set
+color = EmpireShieldManager.i.getShield
 Colo
+u
 r(
+empire);%0A          color = 0x66ffffff & color;%0A        %7D%0A      %7D else %7B%0A        color = 
 Empi
@@ -3912,19 +3912,55 @@
 (empire)
-)
 ;%0A
+      %7D%0A%0A      paint.setColor(color);
 %0A      c
@@ -4622,32 +4622,516 @@
 %0A      %7D%0A    %7D%0A%0A
+    return null;%0A  %7D%0A%0A  /**%0A   * If we can't find an empire by colony, look for a fleet. If there's one, we'll display a circle%0A   * that a little dimmed.%0A   */%0A  private static Empire getFleetOnlyEmpire(Star star) %7B%0A    // TODO: what if there is more than one fleet? Should try to mix the colors.%0A    for (BaseFleet fleet : star.getFleets()) %7B%0A      if (fleet.getEmpireKey() != null) %7B%0A        return EmpireManager.i.getEmpire(Integer.parseInt(fleet.getEmpireKey()));%0A      %7D%0A    %7D%0A%0A
     return null;

Fix #117, draw a semi-transparent circle for stars with only ships.