/*
 * $Id: BulletImpl.java,v 1.2 2002/06/15 14:50:21 kenta Exp $
 *
 * Copyright 2002 Kenta Cho. All rights reserved.
 */
package jp.gr.java_conf.abagames.bulletml2swf;

import jp.gr.java_conf.abagames.bulletml.*;
import jp.gr.java_conf.abagames.util.*;
import com.anotherbigidea.flash.movie.Instance;

/**
 * Bullet implementation.
 *
 * @version $Revision: 1.2 $
 */
public class BulletImpl {
  public static final int NOT_EXIST = Integer.MIN_VALUE;

  private final int ACTION_MAX = 8;

  private ActionImpl[] action = new ActionImpl[ACTION_MAX];
  private int acIdx;

  public int x, y, px, py, width;

  public Direction drcElm;
  public Speed spdElm;
  public float direction, speed;

  public float mx, my;

  public int clr;

  private int cnt;

  private GameManager gameManager;

  private float[] prms;

  private int tmx, tmy;
  private BulletImpl parent;
  public float rank;

  public Instance inst;

  public BulletImpl(GameManager gm) {
    gameManager = gm;
    x = NOT_EXIST;
  }

  public void changeAction(ActionImpl bfr, ActionImpl aft) {
    for ( int i=0 ; i<acIdx ; i++ ) {
      if ( action[i].equals(bfr) ) {
        action[i] = aft;
        return;
      }
    }
  }

  public void set(IActionElmChoice[] aec,
   int x, int y, int d, int clr, float rank) {
    this.x = px = x; this.y = py = y;
    mx = my = 0; tmx = tmy = 0;
    this.clr = clr;
    cnt = 0;
    acIdx = 0;
    for ( int i=0 ; i<aec.length ; i++ ) {
      action[acIdx] = gameManager.getActionImplInstance();
      if ( action[acIdx] == null ) break;
      action[acIdx].set(BulletmlUtil.getActionElm(aec[i]), this);
      float[] actPrms = BulletmlUtil.getActionParams(aec[i], prms);
      if ( actPrms == null ) {
        action[acIdx].setParams(prms);
      } else {
        action[acIdx].setParams(actPrms);
      }
      acIdx++;
      if ( acIdx >= ACTION_MAX ) break;
    }
    direction = d;
    speed = 0;
    this.rank = rank;
    parent = null;
  }

  public void set(Bullet bullet, int x, int y, int ci, BulletImpl bImpl) {
    drcElm = bullet.getDirection();
    spdElm = bullet.getSpeed();
    IActionElmChoice[] aec = bullet.getActionElm();
    set(aec, x, y, 0, ci, bImpl.rank);
    parent = bImpl;
  }

  public void setParams(float[] prms) {
    this.prms = prms;
  }

  public float getAimDeg() {
    return (float)DegUtil.getDeg(gameManager.shipx - x, gameManager.shipy - y)
     * 360 / SCTable.TABLE_SIZE;
  }

  public void vanish() {
    for ( int i=0 ; i<acIdx ; i++ ) {
      action[i].vanish();
    }
    x = NOT_EXIST;
    gameManager.removeBullet(inst);
  }

  public boolean isAllActionFinished() {
    for ( int i=0 ; i<acIdx ; i++ ) {
      if ( action[i].pc != ActionImpl.NOT_EXIST ) {
        return false;
      }
    }
    return true;
  }

  public final void move() {
    BulletmlUtil.setRank(rank);
    for ( int i=0 ; i<acIdx ; i++ ) {
      action[i].move();
    }

    cnt++;

    int d = (int)(direction*SCTable.TABLE_SIZE/360);
    d &= (SCTable.TABLE_SIZE-1);

    int mvx = ((int)(speed*SCTable.sintbl[d])<<1) + (int)(mx*512);
    int mvy = ((int)(-speed*SCTable.costbl[d])<<1) + (int)(my*512);
    int pmvx = mvx, pmvy = mvy;
    x += mvx; tmx = mvx;
    y += mvy; tmy = mvy;
    if ( pmvx == 0 && pmvy == 0 ) {
      pmvx = SCTable.sintbl[d]<<2;
      pmvy = -SCTable.costbl[d]<<2;
    }
    if ( cnt < 4 ) {
      px = x - pmvx;
      py = y - pmvy;
    } else if ( cnt < 8 ) {
      px = x - (pmvx<<1);
      py = y - (pmvy<<1);
    } else {
      px = x - (pmvx<<2);
      py = y - (pmvy<<2);
    }

    /*if ( px < 0 || px >= gameManager.screenWidth ||
         py < 0 || py >= gameManager.screenHeight ) {
      vanish();
    }*/
    if ( acIdx == 0 ) {
      if ( px < 0 || px >= gameManager.screenWidth ||
           py < 0 || py >= gameManager.screenHeight ) {
        vanish();
      }
    } else {
      if ( px < -(gameManager.screenWidth>>2) ||
           px >=  gameManager.screenWidth+(gameManager.screenWidth>>2) ||
           py < -(gameManager.screenHeight>>2) ||
           py >=  gameManager.screenHeight+(gameManager.screenHeight>>2) ) {
        vanish();
      }
    }
  }

  public final void draw() {
    int d = DegUtil.getDeg(px-x, py-y);
    gameManager.drawBullet(((double)x/256), ((double)y/256), d, clr, inst);
  }
}
