#ifndef _gpuCacheMaterialNodes_h_
#define _gpuCacheMaterialNodes_h_
#include "gpuCacheMaterial.h"
namespace GPUCache {
class SurfaceMaterial : public MaterialNode
{
public:
    SurfaceMaterial(
const MString& name, 
const MString& type = 
"surfaceShader");
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef OutColor;
    MaterialPropertyRef OutTransparency;
};
class SurfaceMaterialVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const SurfaceMaterial& node) = 0;
};
class LambertMaterial : public SurfaceMaterial
{
public:
    LambertMaterial(
const MString& name, 
const MString& type = 
"lambert");
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef Color;
    MaterialPropertyRef Transparency;
    MaterialPropertyRef AmbientColor;
    MaterialPropertyRef Incandescence;
    MaterialPropertyRef Diffuse;
    MaterialPropertyRef Translucence;
    MaterialPropertyRef TranslucenceDepth;
    MaterialPropertyRef TranslucenceFocus;
    MaterialPropertyRef HideSource;
    MaterialPropertyRef GlowIntensity;
};
class LambertMaterialVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const LambertMaterial& node) = 0;
};
class PhongMaterial : public LambertMaterial
{
public:
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef CosinePower;
    MaterialPropertyRef SpecularColor;
    MaterialPropertyRef Reflectivity;
    MaterialPropertyRef ReflectedColor;
};
class PhongMaterialVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const PhongMaterial& node) = 0;
};
class BlinnMaterial : public LambertMaterial
{
public:
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef Eccentricity;
    MaterialPropertyRef SpecularRollOff;
    MaterialPropertyRef SpecularColor;
    MaterialPropertyRef Reflectivity;
    MaterialPropertyRef ReflectedColor;
};
class BlinnMaterialVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const BlinnMaterial& node) = 0;
};
class Texture2d : public MaterialNode
{
public:
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef DefaultColor;
    MaterialPropertyRef OutColor;
    MaterialPropertyRef OutAlpha;
};
class Texture2dVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const Texture2d& node) = 0;
};
class FileTexture : public Texture2d
{
public:
    virtual void accept(MaterialNodeVisitor& visitor) const;
public:
    MaterialPropertyRef OutTransparency;
    MaterialPropertyRef FileTextureName;
    
};
class FileTextureVisitor : public virtual MaterialNodeVisitor
{
public:
    virtual void visit(const FileTexture& node) = 0;
};
class UnknownTexture2d : public Texture2d
{
public:
    UnknownTexture2d(
const MString& name, 
const MString& type = 
"unknownTexture2d");
    virtual void accept(MaterialNodeVisitor& visitor) const;
};
class UnknownTexture2dVisitor : public virtual MaterialNodeVisitor
{
public:
    
    virtual void visit(const UnknownTexture2d& node) {}
};
class UnknownMaterialNode : public MaterialNode
{
public:
    UnknownMaterialNode(
const MString& name, 
const MString& type = 
"unknown");
    virtual void accept(MaterialNodeVisitor& visitor) const;
};
class UnknownMaterialNodeVisitor : public virtual MaterialNodeVisitor
{
public:
    
    virtual void visit(const UnknownMaterialNode& node) {}
};
class ConcreteMaterialNodeVisitor :
    public SurfaceMaterialVisitor,
    public LambertMaterialVisitor,
    public PhongMaterialVisitor,
    public BlinnMaterialVisitor,
    public Texture2dVisitor,
    public FileTextureVisitor,
    public UnknownTexture2dVisitor,
    public UnknownMaterialNodeVisitor
{};
} 
#endif