
// Obstacles.java
// Sirinart Sakarin, March 2003, s4210315@calvin.coe.psu.ac.th
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th


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

import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;


public class Obstacles
{
  private final static int FLOOR_LEN = 20;  
      // mělo by být sudé a stejné jako velikost podlahy ve třídě CheckerFloor
  private final static float MAX_HEIGHT = 8.0f;  
  private final static float RADIUS = 0.3f;  


  private ArrayList obsList;   // seznam ohraničujících boxů
  private BranchGroup obsBG;   // překážky ve scéně
  

  public Obstacles(int numObs)
  {
    System.out.println("Num. Obstacles: "+ numObs);     

    obsList = new ArrayList();
    obsBG = new BranchGroup();

    Appearance blueApp = makeBlueApp();
 
    float x, z, height;
    Point3d lower, upper;
    BoundingBox bb;
    for (int i=0 ; i < numObs; i++) {
      // překážka je na náhodně zvolené pozici a je nižší než maximální výška
      x = randomFloorPosn();
      z = randomFloorPosn();
      height = (float)(Math.random()*MAX_HEIGHT);  
      lower = new Point3d( x-RADIUS, 0.0f, z-RADIUS );
      upper = new Point3d( x+RADIUS, height, z+RADIUS );

      bb = new BoundingBox(lower, upper);
      obsList.add(bb);

      obsBG.addChild( makeSceneOb(height,x,z, blueApp) );
    }
  } // konec konstruktoru: Obstacles()


  private float randomFloorPosn()
  // vrátí reálné číslo mezi -FLOOR_LEN/2 a FLOOR_LEN/2
  {
    return (float)((Math.random()*FLOOR_LEN)-(FLOOR_LEN/2));
  }


  private Appearance makeBlueApp()
  {
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f blue = new Color3f(0.3f, 0.3f, 0.8f);
    Color3f specular = new Color3f(0.9f, 0.9f, 0.9f);

    Material blueMat = new Material(blue, black, blue, specular, 80.0f);
    blueMat.setLightingEnable(true);
    
    Appearance blueApp = new Appearance();
    blueApp.setMaterial(blueMat);
    return blueApp;
  }// konec metody: createObstacle()


  private TransformGroup makeSceneOb(float height, float x, float z,
                                        Appearance blueApp)
  {
    Cylinder cyl = new Cylinder(RADIUS, height, blueApp);

    // oprav pozici překážky
    TransformGroup tg = new TransformGroup();
    Transform3D trans = new Transform3D();
    trans.setTranslation( new Vector3d(x, height/2, z) );
    tg.setTransform(trans);
    tg.addChild(cyl); 
    return tg;
  }  // konec metody: makeSceneOb()


  public BranchGroup getObsBG()
  {  return obsBG;  }
    

  public boolean isOverlapping(BoundingSphere bs)
  // Protíná ohraničující koule (bs) ohraničující box kterékoliv 
  // překážky?
  {
    BoundingBox bb;
    for (int i=0; i < obsList.size(); i++) {
      bb = (BoundingBox)obsList.get(i);
      if( bb.intersect(bs) )
        return true;
    }
    return false;
  } // konec metody: isOverlapping()


} // konec třídy: Obstacles

