//
//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
//POSSIBILITY OF SUCH DAMAGE.
//

#ifndef _SHHANDLE_INCLUDED_
#define _SHHANDLE_INCLUDED_

//
// Machine independent part of the compiler private objects
// sent as ShHandle to the driver.
//
// This should not be included by driver code.
//


#define SH_EXPORTING   
#include "../Public/ShaderLang.h"
#include "../MachineIndependent/Versions.h"
#include "InfoSink.h"

class TCompiler;
class TLinker;
class TUniformMap;

//
// The base class used to back handles returned to the driver.
//
class TShHandleBase {
public:
    TShHandleBase() { }
    virtual ~TShHandleBase() { }
    virtual TCompiler* getAsCompiler() { return 0; }
    virtual TLinker* getAsLinker() { return 0; }
    virtual TUniformMap* getAsUniformMap() { return 0; }
};

//
// The base class for the machine dependent linker to derive from
// for managing where uniforms live.
//
class TUniformMap : public TShHandleBase {
public:
    TUniformMap() { }
    virtual ~TUniformMap() { }
    virtual TUniformMap* getAsUniformMap() { return this; }
    virtual int getLocation(const char* name) = 0;    
    virtual TInfoSink& getInfoSink() { return infoSink; }
    TInfoSink infoSink;
};

class TIntermNode;

//
// The base class for the machine dependent compiler to derive from
// for managing object code from the compile.
//
class TCompiler : public TShHandleBase {
public:
    TCompiler(EShLanguage l, TInfoSink& sink) : infoSink(sink) , language(l), haveValidObjectCode(false) { }
    virtual ~TCompiler() { }
    EShLanguage getLanguage() { return language; }
    virtual TInfoSink& getInfoSink() { return infoSink; }

    virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile) = 0;

    virtual TCompiler* getAsCompiler() { return this; }
    virtual bool linkable() { return haveValidObjectCode; }
    
    TInfoSink& infoSink;
protected:
    TCompiler& operator=(TCompiler&);

    EShLanguage language;
    bool haveValidObjectCode;
};

//
// Link operations are based on a list of compile results...
//
typedef glslang::TVector<TCompiler*> TCompilerList;
typedef glslang::TVector<TShHandleBase*> THandleList;

//
// The base class for the machine dependent linker to derive from
// to manage the resulting executable.
//

class TLinker : public TShHandleBase {
public:
    TLinker(EShExecutable e, TInfoSink& iSink) : 
        infoSink(iSink),
        executable(e), 
        haveReturnableObjectCode(false),
        appAttributeBindings(0),
        fixedAttributeBindings(0),
        excludedAttributes(0),
        excludedCount(0),
        uniformBindings(0) { }
    virtual TLinker* getAsLinker() { return this; }
    virtual ~TLinker() { }
    virtual bool link(TCompilerList&, TUniformMap*) = 0;
    virtual bool link(THandleList&) { return false; }
    virtual void setAppAttributeBindings(const ShBindingTable* t)   { appAttributeBindings = t; }
    virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
    virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
    virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
    virtual ShBindingTable* getUniformBindings() const  { return uniformBindings; }
    virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here
    virtual TInfoSink& getInfoSink() { return infoSink; }
    TInfoSink& infoSink;
protected:
    TLinker& operator=(TLinker&);
    EShExecutable executable;
    bool haveReturnableObjectCode;  // true when objectCode is acceptable to send to driver

    const ShBindingTable* appAttributeBindings;
    const ShBindingTable* fixedAttributeBindings;
    const int* excludedAttributes;
    int excludedCount;
    ShBindingTable* uniformBindings;                // created by the linker    
};

//
// This is the interface between the machine independent code
// and the machine dependent code.
//
// The machine dependent code should derive from the classes
// above. Then Construct*() and Delete*() will create and 
// destroy the machine dependent objects, which contain the
// above machine independent information.
//
TCompiler* ConstructCompiler(EShLanguage, int);

TShHandleBase* ConstructLinker(EShExecutable, int);
TShHandleBase* ConstructBindings();
void DeleteLinker(TShHandleBase*);
void DeleteBindingList(TShHandleBase* bindingList);
    
TUniformMap* ConstructUniformMap();
void DeleteCompiler(TCompiler*);

void DeleteUniformMap(TUniformMap*);

#endif // _SHHANDLE_INCLUDED_
