/*
 * Copyright 1993 by Cub'x Systemes
 * 
 * All Rights Reserved
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for the  purpose of making new intuitiv'3d modules.
 * This copyright notice must appears in all copies that you distribute.
 * The name of Cub'x Systeme should not be used in advertising or publicity
 * without specific, written prior permission. 
 * CUB'X SYSTEMES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * CUB'X SYSTEMES BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
 

/******************************************************************************* 
 *                                                                             *
 *     Project intuitiv'3d                                                     *
 *     -------------------                                                     *
 *                                                                             *
 *                                                                             *
 *     File: ColoredPlan.m                                                     *
 *                                                                             *
 *                                                                             *
 *     Creation date: Mon Jul 26 11:52:40 GMT+0200 1993                        *
 *                                                                             *
 *                                                                             *
 *     Contents:  A plan that includes colors or opacity parameters            *
 *                This object is made to be an example illustrating the        *
 *                CX3DAttributeInsp object                                     *
 *                                                                             *
 *******************************************************************************/

#import "ColoredPlan.h"
#import <ri/ri.h>
#import <i3d/CX3DAttributeInsp.h>

#define VERSION 0

/*
 *  This is a constant array returned to describe the inspector
 */
static AIParameter param[7];

@implementation ColoredPlan

/*
 *  ExportedVariables allows you to speedup the implementation of the read: and
 *  write: methods. Please read the documentation.
 */
+ (ExportedVariable*) exportedVariable
{
  static ExportedVariable ev[] = {
    {"size",EV_FLOAT,0},
    {"up_left",EV_NXCOLOR,0},
    {"up_right",EV_NXCOLOR,0},
    {"down_left",EV_NXCOLOR,0},
    {"down_right",EV_NXCOLOR,0},
    {"use_opacity",EV_BOOL,0},
    {NULL,EV_NULL,0}};
  return ev;
}

/*
 * Sets the version of the class.
 * Initialize the array param which is returned by the method AIparameters.
 */
+ initialize
{
  [self setVersion: VERSION];

  param[0].type = AIP_FLOAT;
  param[0].dynamicBound = NO;
  strcpy(param[0].parameterName,"Size");
  param[0].data.floatp.setValueMethod = @selector(setSize:);
  param[0].data.floatp.getValueMethod = @selector(size:);
  param[0].data.floatp.getMinValueMethod = @selector(getMinValue:);
  param[0].data.floatp.getMaxValueMethod = @selector(getMaxValue:);

  param[1].type = AIP_COLOR;
  param[1].dynamicBound = NO;
  strcpy(param[1].parameterName,"Up left color");
  param[1].data.colorp.setRedValueMethod   = @selector(setRedValueUL:);
  param[1].data.colorp.setGreenValueMethod = @selector(setGreenValueUL:);
  param[1].data.colorp.setBlueValueMethod  = @selector(setBlueValueUL:);
  param[1].data.colorp.getRedValueMethod   = @selector(getRedValueUL:);
  param[1].data.colorp.getGreenValueMethod = @selector(getGreenValueUL:);
  param[1].data.colorp.getBlueValueMethod  = @selector(getBlueValueUL:);

  param[2].type = AIP_COLOR;
  param[2].dynamicBound = NO;
  strcpy(param[2].parameterName,"Up right color");
  param[2].data.colorp.setRedValueMethod   = @selector(setRedValueUR:);
  param[2].data.colorp.setGreenValueMethod = @selector(setGreenValueUR:);
  param[2].data.colorp.setBlueValueMethod  = @selector(setBlueValueUR:);
  param[2].data.colorp.getRedValueMethod   = @selector(getRedValueUR:);
  param[2].data.colorp.getGreenValueMethod = @selector(getGreenValueUR:);
  param[2].data.colorp.getBlueValueMethod  = @selector(getBlueValueUR:);

  param[3].type = AIP_COLOR;
  param[3].dynamicBound = NO;
  strcpy(param[3].parameterName,"Down left color");
  param[3].data.colorp.setRedValueMethod   = @selector(setRedValueDL:);
  param[3].data.colorp.setGreenValueMethod = @selector(setGreenValueDL:);
  param[3].data.colorp.setBlueValueMethod  = @selector(setBlueValueDL:);
  param[3].data.colorp.getRedValueMethod   = @selector(getRedValueDL:);
  param[3].data.colorp.getGreenValueMethod = @selector(getGreenValueDL:);
  param[3].data.colorp.getBlueValueMethod  = @selector(getBlueValueDL:);

  param[4].type = AIP_COLOR;
  param[4].dynamicBound = NO;
  strcpy(param[4].parameterName,"Down right color");
  param[4].data.colorp.setRedValueMethod   = @selector(setRedValueDR:);
  param[4].data.colorp.setGreenValueMethod = @selector(setGreenValueDR:);
  param[4].data.colorp.setBlueValueMethod  = @selector(setBlueValueDR:);
  param[4].data.colorp.getRedValueMethod   = @selector(getRedValueDR:);
  param[4].data.colorp.getGreenValueMethod = @selector(getGreenValueDR:);
  param[4].data.colorp.getBlueValueMethod  = @selector(getBlueValueDR:);

  param[5].type = AIP_BOOL;
  param[5].dynamicBound = NO;
  strcpy(param[5].parameterName,"Colors stands for:");
  param[5].data.boolp.setBoolValue = @selector(setUseOpacity:);
  param[5].data.boolp.getBoolValue = @selector(useOpacity);
  strcpy(param[5].data.boolp.trueTitle,"Opacity");
  strcpy(param[5].data.boolp.falseTitle,"Color");

  /*
   *  Always end by this
   */
  param[6].type = AIP_NULL;

  return [super initialize];
}

/*******************************************************************************
 *                                                                             *
 *                               Instance methods                              *
 *                                                                             *
 *******************************************************************************/

/*
 *  The init method should set some default values to your instance variables.
 */
- init
{
  [super init];
  size  = 2.0;
  up_left = up_right = down_left = down_right = NX_COLORWHITE;
  use_opacity = NO;

  /*
   *  N3DPlan is a tiff of the main bundle
   */
  [self setIconFromMachO:"N3DPlan"];
  CX(rotate) = 90.0;
  return self;
}

/*
 *  The copy method should be implemented. 
 *  Duplicate the receiver.
 */
- copy
{
  ColoredPlan *obj = [super copy];
  obj->size  = size;
  obj->up_right = up_right;
  obj->up_left  = up_left;
  obj->down_right = down_right;
  obj->down_left  = down_left;
  obj->use_opacity = use_opacity;
  return obj;
}

/*
 *  This method renders the object.
 *  You can use Renderman functiona inside
 *  this method. You should begin this method
 *  by if( [super render] ) { ... 
 */
- render
{
  if( [super render] )
    {
      RtPoint coord[4],col[4];

      CX( coord[0] ) = -(size  / 2); CRED(   col[0]) = NXRedComponent(   up_left );
      CY( coord[0] ) =  (size / 2); CGREEN( col[0]) = NXGreenComponent( up_left );
      CZ( coord[0] ) = 0;             CBLUE(  col[0]) = NXBlueComponent(  up_left );


      CX( coord[2] ) = size / 2;     CRED(   col[1]) = NXRedComponent(   down_left );
      CY( coord[2] ) = size / 2;    CGREEN( col[1]) = NXGreenComponent(  down_left );
      CZ( coord[2] ) = 0;             CBLUE(  col[1]) = NXBlueComponent( down_left );

      CX( coord[1] ) = -(size / 2);  CRED(   col[2]) = NXRedComponent(    up_right );
      CY( coord[1] ) = -(size / 2); CGREEN( col[2]) = NXGreenComponent(   up_right );
      CZ( coord[1] ) = 0;             CBLUE(  col[2]) = NXBlueComponent(  up_right );

      CX( coord[3] ) = (size / 2);   CRED(   col[3]) = NXRedComponent(    down_right );
      CY( coord[3] ) = -(size / 2); CGREEN( col[3]) = NXGreenComponent(   down_right );
      CZ( coord[3] ) = 0;             CBLUE(  col[3]) = NXBlueComponent(  down_right );

      if( use_opacity )
	RiPatch("bilinear",RI_P,(RtPointer) coord,RI_OS, (RtPointer) col, RI_NULL);
      else
	RiPatch("bilinear",RI_P,(RtPointer) coord,RI_CS, (RtPointer) col, RI_NULL);
    }
  return self;
}

/*
 *  This method should return the bounding box of your instance.
 *  You have to implement this method.
 */
- getBoundingBox:(RtBound) aBox
{
  aBox[0] = - (size / 2);
  aBox[1] =   (size / 2);
  aBox[2] = - (size / 2);
  aBox[3] =   (size / 2);
  aBox[4] = 0.0;
  aBox[5] = 0.0;
  return self;
}

- setSize:(float*) v   { size = *v; return self; }
- size:(float*) v      { *v = size; return self; }
- getMinValue:(float*)v { *v = 0.0; return self; }
- getMaxValue:(float*)v { *v = 2.0; return self; }


- setRedValueUL:(float*)v
{
  up_left = NXConvertRGBToColor(*v,NXGreenComponent(up_left),NXBlueComponent(up_left));
  return self;
}

- setGreenValueUL:(float*)v
{
  up_left = NXConvertRGBToColor(NXRedComponent(up_left),*v,  NXBlueComponent(up_left));
  return self;
}

- setBlueValueUL:(float*)v  
{
  up_left = NXConvertRGBToColor(NXRedComponent(up_left),NXGreenComponent(up_left), *v);
  return self; 
}

- setRedValueUR:(float*)v
{
  up_right = NXConvertRGBToColor(*v,NXGreenComponent(up_right),NXBlueComponent(up_right));
  return self;
}

- setGreenValueUR:(float*)v
{
  up_right = NXConvertRGBToColor(NXRedComponent(up_right),*v,  NXBlueComponent(up_right));
  return self;
}

- setBlueValueUR:(float*)v  
{
  up_right = NXConvertRGBToColor(NXRedComponent(up_right),NXGreenComponent(up_right), *v);
  return self; 
}


- setRedValueDL:(float*)v
{
  down_left = NXConvertRGBToColor(*v,NXGreenComponent(down_left),NXBlueComponent(down_left));
  return self;
}

- setGreenValueDL:(float*)v
{
  down_left = NXConvertRGBToColor(NXRedComponent(down_left),*v,  NXBlueComponent(down_left));
  return self;
}

- setBlueValueDL:(float*)v  
{
  down_left = NXConvertRGBToColor(NXRedComponent(down_left),NXGreenComponent(down_left), *v);
  return self; 
}

- setRedValueDR:(float*)v
{
  down_right = NXConvertRGBToColor(*v,NXGreenComponent(down_right),NXBlueComponent(down_right));
  return self;
}

- setGreenValueDR:(float*)v
{
  down_right = NXConvertRGBToColor(NXRedComponent(down_right),*v,  NXBlueComponent(down_right));
  return self;
}

- setBlueValueDR:(float*)v  
{
  down_right = NXConvertRGBToColor(NXRedComponent(down_right),NXGreenComponent(down_right), *v);
  return self; 
}



- getRedValueUL:  (float*) v  {  *v = NXRedComponent(up_left);   return self; }
- getGreenValueUL:(float*) v  {  *v = NXGreenComponent(up_left); return self; }
- getBlueValueUL: (float*) v  {  *v = NXBlueComponent(up_left);  return self; }

- getRedValueUR:  (float*) v  {  *v = NXRedComponent(up_right);   return self; }
- getGreenValueUR:(float*) v  {  *v = NXGreenComponent(up_right); return self; }
- getBlueValueUR: (float*) v  {  *v = NXBlueComponent(up_right);  return self; }

- getRedValueDL:  (float*) v  {  *v = NXRedComponent(down_left);   return self; }
- getGreenValueDL:(float*) v  {  *v = NXGreenComponent(down_left); return self; }
- getBlueValueDL: (float*) v  {  *v = NXBlueComponent(down_left);  return self; }

- getRedValueDR:  (float*) v  {  *v = NXRedComponent(down_right);   return self; }
- getGreenValueDR:(float*) v  {  *v = NXGreenComponent(down_right); return self; }
- getBlueValueDR: (float*) v  {  *v = NXBlueComponent(down_right);  return self; }


- setUseOpacity:(BOOL) aFlag
{
  use_opacity = aFlag;
  return self;
}

- (BOOL) useOpacity
{
  return use_opacity;
}

- attributeInspClass
{
  return [CX3DAttributeInsp class];
}

- (AIParameter*) AIparameters
{
  return param;
}

- (const char*) inspectorName
{
  return "Colored Plane attributes";
}

@end




