package modeler;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.vecmath.Matrix4f;

import modeler.shape.Sphere;
import net.java.games.jogl.GL;

/**
 * Light object.  Also includes functions to map light objects to OpenGL lights
 * @author ags
 */
public class Light extends Treeable { 

  /** Constant light parameters */
  public final float[] diffuse = new float[] { 1, 1, 1, 1 };
  public final float[] specular = new float[] { 0.4f, 0.4f, 0.4f, 1 };
  public final float[] position = new float[] { 1, 1, 1, 1 };
  
  /** Map of all 8 GL lights */
  protected final static boolean[] taken = { false, false, false, false, false, false, false, false };
  protected final static int[] ids = { GL.GL_LIGHT0, GL.GL_LIGHT1, GL.GL_LIGHT2, GL.GL_LIGHT3, GL.GL_LIGHT4, GL.GL_LIGHT5, GL.GL_LIGHT6, GL.GL_LIGHT7 };

  /** Sphere to use when rendering */
  protected Sphere sphere = new Sphere();
  
  /** This lights ID and index in the GL map */
  public int id;
  protected int index;

  /** Lights name and icon */
  protected transient Icon icon = new ImageIcon("../icons/light.gif");

  /**
   * Required for IO
   */
  protected Light() {}
  
  /**
   * Constructor
   * @param newIndex
   */
  private Light(int newIndex) {

    index = newIndex;
    if (index != -1) {
      id = ids[index];
    }
    setName("Light " + index);
  }
  
  /**
   * @see modeler.Treeable#getIcon()
   */
  public Icon getIcon() {

    if(icon == null)
      icon = new ImageIcon("../icons/light.gif");
    return icon;
  }

  /**
   * Create a new light which is on or off depending on enabled.
   * @param enabled
   * @return
   */
  public static synchronized Light makeNewLight(boolean enabled) {

    if (!enabled) {
      return new Light(-1);
    }

    for (int ctr = 0; ctr < taken.length; ctr++) {
      if (taken[ctr] == false) {
        taken[ctr] = true;
        return new Light(ctr);
      }
    }
    return null;
  }

  /**
   * Enable the lights in the scene
   */
  public static synchronized void turnOnLights(GL gl) {

    for (int ctr = 0; ctr < taken.length; ctr++) {
      if (taken[ctr]) {
        gl.glEnable(ids[ctr]);
      }
      else {
        gl.glDisable(ids[ctr]);
      }
    }
  }

  /**
   * Unmap a light from the OpenGL map
   * @param l
   */
  public static synchronized void returnLight(Light l) {

    taken[l.index] = false;
  }

  /**
   * @see modeler.Treeable#render(net.java.games.jogl.GL, javax.vecmath.Matrix4f)
   */
  public void render(GL gl, Matrix4f currMat) {

    
    super.render(gl, currMat);
    
  }
  

  /**
   * @see modeler.Treeable#getAttributePanel(modeler.MainFrame)
   */
  public ItemAttributePanel getAttributePanel(MainFrame mainFrame) {

    return ItemAttributePanel.EMPTY_PANEL;
  }
  
  /**
   * @throws IOException 
   * @see modeler.Treeable#readData(java.io.ObjectInputStream)
   */
  protected void readData(ObjectInputStream in) throws IOException {

    id = in.readInt();
    index = in.readInt();
    if(index >= 0)
      taken[index] = true;
    
  }

  /**
   * @throws IOException 
   * @see modeler.Treeable#saveData(java.io.ObjectOutputStream)
   */
  protected void saveData(ObjectOutputStream out) throws IOException {

    out.writeInt(id);
    out.writeInt(index);
    
  }

  /**
   * @see modeler.Treeable#exportMainData(java.util.HashMap, java.io.PrintWriter)
   */
  protected void exportMainData(HashMap materialsMap, PrintWriter pw) {

    pw.println("  <light>");
    pw.println("    <location>"+position[0]+" "+(position[1]+30)+" "+position[2]+"</location>");
    pw.println("    <power>"+(diffuse[0]*100)+" "+(diffuse[1]*100)+" "+(diffuse[2]*100)+"</power>");
    pw.println("  </light>");
    
  }
  
  /**
   * @see javax.swing.tree.TreeNode#getAllowsChildren()
   */
  public boolean getAllowsChildren() {

    return false;

  }

  /**
   * @see javax.swing.tree.TreeNode#isLeaf()
   */
  public boolean isLeaf() {

    return true;

  }
}
