////////////////////////////////////////////////////////////////////////////////
// <copyright>
// Copyright (c) 2015 Hue AS. All rights reserved.
//
// All rights are reserved. Reproduction or transmission in whole or in part, in
// any form or by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written permission of the copyright owner.
// </copyright>
////////////////////////////////////////////////////////////////////////////////


// Property definitions and bindings

PROPERTY_DEFINITIONS


/////////////////////////////////////////////////////////////////////////////
// CellDataFetch
//

float
CellDataFetch(int iProperty, int nCell)
{
  
  PROPERTY_TEXELFETCH

  return 0.0f;    // Error

}

/////////////////////////////////////////////////////////////////////////////
// CellDataTextureSize
//

int
CellDataTextureSize(int iProperty)
{
  PROPERTY_TEXTURE_SIZE

  return 0; // Error
}


#if (PROPERTIES > 0)

uniform float rPropertyNoValueFloat[PROPERTIES];
uniform bool isPropertyNoValueVisible[PROPERTIES];

#endif



/////////////////////////////////////////////////////////////////////////////
// GetPropertyBool
//

#if (PROPERTIES > 0)

float
GetPropertyBool(int iProperty, int nCellID, out bool isPropertyNoValue)
{
  float
    rPropertyValue;

  int
    nCells = 8 * CellDataTextureSize(iProperty);

  if (nCellID < 0 || nCellID >= nCells)
  {
    rPropertyValue = 0.f;
  }          
  else
  {
    int
      nCellIDBytePosition = nCellID / 8;

    uint
      uCellIDBit =  uint( nCellID % 8);

    float
      rValue = CellDataFetch(iProperty, nCellIDBytePosition);

    uint
      uValue = uint (rValue * 255.f);

    uint
      uValueBit = (uValue >> uCellIDBit) & 1u;

    rPropertyValue = (uValueBit != 0) ? 1.f : 0.f;

   }

   // No 'no value' support for bool
   isPropertyNoValue = false;

  return rPropertyValue;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// GetPropertyNonBool
//

#if (PROPERTIES > 0)

float
GetPropertyNonBool(int iProperty, int nCellID, out bool isPropertyNoValue)
{
  float
    rPropertyValue;

  int
    nCells = CellDataTextureSize(iProperty);
          
  if (nCellID < 0 || nCellID >= nCells)
  {
    rPropertyValue = rPropertyNoValueFloat[iProperty];
  }          
  else
  {
    rPropertyValue = CellDataFetch(iProperty, nCellID);
  }

  isPropertyNoValue = (rPropertyValue == rPropertyNoValueFloat[iProperty]);

  return rPropertyValue;
}

#endif

/////////////////////////////////////////////////////////////////////////////
// IsVisible
//

bool
IsVisible(ivec3 iMin, ivec3 iMax)
{

  for (int z_in = iMin.z; z_in < iMax.z; z_in++)
  {
    for (int y_in = iMin.y; y_in < iMax.y; y_in++)
    {
      for (int x_in = iMin.x; x_in < iMax.x ; x_in++)
      {
        bool
          isVoxelNoValue = false;

        int
          nCellID;

        float
          rVoxel0;

        GetVoxel(x_in, y_in, z_in, rVoxel0, nCellID, isVoxelNoValue);

#ifdef USE_VOLUME_NO_VALUE

        if (isVoxelNoValue)
        {
          if (isVoxelNoValueColorVisible)
          {
            return true;
          }
          else
          {
            continue;
          }
        }
 #endif

#undef IS_NO_VALUE_CHECK_ONLY

#ifndef IS_VISIBLE_VOXEL_OPERATION
#ifndef IS_VISIBLE_PROPERTY_OPERATION

#define IS_NO_VALUE_CHECK_ONLY

#endif
#endif



#ifdef IS_VISIBLE_VOXEL_OPERATION

        bool
          isVisibleVoxel = IS_VISIBLE_VOXEL_OPERATION;

	    if (isVisibleVoxel)
	    {
		  return true;
	    }
#endif

#ifdef PROPERTY_READ_OUT

        bool
          isPropertyNoValue = false;

        PROPERTY_READ_OUT
#endif


#ifdef IS_VISIBLE_PROPERTY_OPERATION

        bool
          isVisibleProperty = IS_VISIBLE_PROPERTY_OPERATION;

        if (isVisibleProperty)
        {
          return true;
        }
#endif

#ifdef IS_NO_VALUE_CHECK_ONLY
        return true;
#endif


      }
    }
  }

  return false;             
}

