/* Copyright (C) 1999-2003 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion;

//import artofillusion.animation.*;
//import artofillusion.image.*;
//import artofillusion.material.*;
import artofillusion.math.*;
import artofillusion.object.*;
import artofillusion.texture.*;
//import java.awt.*;
//import java.io.*;
//import java.lang.reflect.*;
//import java.util.*;
//import java.util.zip.*;

/** Presents a modified set (not necessary subset) of the objects of
  an underlying scene to a renderer. It is allowed that the same object is
  shared by one or more SceneSubset and at most one Scene object
 
  @author Michael Butscher
*/


public class SceneSubset implements SceneRenderInfoProvider, SceneEnvironmentData
{
  protected SceneRenderInfoProvider realInfo;
  protected int[] aboveToBelowMapping;
  RGBColor ambientColor, environColor, fogColor;
  int environMode;
  Texture environTexture;
  TextureMapping environMapping;
  ParameterValue environParamValue[];
  double fogDist;
  boolean fog;
  
  /** Constructor.
    
    @param realInfo Underlying scene information
  */
  public SceneSubset(SceneRenderInfoProvider realInfo)
  {
    this.realInfo = realInfo;
  }
  
  /** Set the number mapping. getObject(i) returns object with index
    mapping[i] in the underlying realInfo scene data. If mapping is null,
    the set of the underlying realInfo is used.
  */
  public void setIndexMapping(int[] mapping)
  {
    aboveToBelowMapping = mapping;
  }  
  
  /** Get the current time. */

  public double getTime()
  {
    return realInfo.getTime();
  }

  /** Get the scene's ambient light color. */

  public RGBColor getAmbientColor()
  {
    if (ambientColor == null)
      return realInfo.getAmbientColor();
    else
      return ambientColor;
  }

  /** Get the Scene's environment mapping mode.  This will be either ENVIRON_SOLID, ENVIRON_DIFFUSE, or
      ENVIRON_EMISSIVE. */

  public int getEnvironmentMode()
  {
    if (environMode == ENVIRON_UNDEFINED)
      return realInfo.getEnvironmentMode();
    else
      return environMode;
  }
  
  /** Get the texture being used as an environment mapping. */

  public Texture getEnvironmentTexture()
  {
    if (environTexture == null)
      return realInfo.getEnvironmentTexture();
    else
      return environTexture;
  }

  /** Get the TextureMapping being used to map the environment map texture to the environment sphere. */

  public TextureMapping getEnvironmentMapping()
  {
    if (environMapping == null)
      return realInfo.getEnvironmentMapping();
    else
      return environMapping;
  }

  /** Get the parameter values used for the environment map. */
  
  public ParameterValue [] getEnvironmentParameterValues()
  {
    if (environParamValue == null)
      return realInfo.getEnvironmentParameterValues();
    else
      return environParamValue;
  }

  /** Get the environment color. */

  public RGBColor getEnvironmentColor()
  {
    if (environColor == null)
      return realInfo.getEnvironmentColor();
    else
      return environColor;
  }
  
  /** Get the fog color. */

  public RGBColor getFogColor()
  {
    if (fogColor == null)
      return realInfo.getFogColor();
    else
      return fogColor;
  }

  /** Determine whether fog is enabled. */

  public boolean getFogState()
  {
    if (fogColor == null)
      return realInfo.getFogState();
    else
      return fog;
  }

  /** Get the length constant for exponential fog. */

  public double getFogDistance()
  {
    if (fogColor == null)
      return realInfo.getFogDistance();
    else
      return fogDist;
  }
  
  /** Set the scene's ambient light color. If parameter is null, the value of
    the underlying SceneInfoProvider is used. */

  public void setAmbientColor(RGBColor ac)
  {
    ambientColor = ac;
  }

  /** Set the Scene's environment mapping mode.  This will be either ENVIRON_SOLID, ENVIRON_DIFFUSE, or
    ENVIRON_EMISSIVE or ENVIRON_UNDEFINED. If ENVIRON_UNDEFINED is used,
    the value of the underlying SceneInfoProvider is used. */

  public void setEnvironmentMode(int em)
  {
    environMode = em;
  }
  
  /** Set the texture being used as an environment mapping. If parameter is
    null, the value of the underlying SceneInfoProvider is used. */

  public void setEnvironmentTexture(Texture et)
  {
    environTexture = et;
  }

  /** Set the TextureMapping being used to map the environment map texture to
    the environment sphere. If parameter is null, the value of the underlying
    SceneInfoProvider is used.*/

  public void setEnvironmentMapping(TextureMapping em)
  {
    environMapping = em;
  }
  
  /** Set the parameter values used for the environment map. */
  
  public void setEnvironmentParameterValues(ParameterValue value[])
  {
    environParamValue = value;
  }

  /** Get the environment color. If parameter is null, the value of the
    underlying SceneInfoProvider is used.*/

  public void setEnvironmentColor(RGBColor ec)
  {
    environColor = ec;
  }
  
  /** Get the fog color. If parameter is null, the value of the underlying
    SceneInfoProvider is used.*/

  public void setFogColor(RGBColor fc)
  {
    fogColor = fc;
  }

  /** Set fog. If fog color is null, the value of the
   underlying SceneInfoProvider is used for the getter.*/

  public void setFog(boolean fs, double fd)
  {
    fog = fs;
    fogDist = fd;
  }

//  /** Set the length constant for exponential fog. If fog color is null, the
//   value of the underlying SceneInfoProvider is used for the getter.*/
//
//  public void setFogDistance(double fd)
//  {
//    fogDist = fd;
//  }
  
  /** Get the number of objects in this scene. */

  public int getNumObjects()
  {
    if (aboveToBelowMapping == null)
      return realInfo.getNumObjects();
    else
      return aboveToBelowMapping.length;
  }

  /** Get the i'th object. */

  public ObjectInfo getObject(int i)
  {
    if (aboveToBelowMapping == null)
      return realInfo.getObject(i);
    else
      return realInfo.getObject(aboveToBelowMapping[i]);
  }
  
}

