#pragma once

#include "binding/AbstractBindingProvider.h"
#include <boost/thread/mutex.hpp>

class AbstractDataTableBindingProvider : public AbstractBindingProvider
{
private:
    std::map<ReferenceListenerPtr, ReferencePtr> listeners;
    boost::mutex listenersLock;

private:
    void writeToEditor(const AgString & property, AgObjectPtr value);
    void writeToField(int row, const AgString & field, const AgString & property, AgObjectPtr value);

public:
    AbstractDataTableBindingProvider();
    AbstractDataTableBindingProvider(ErrorCollectorPtr errorCollector);
    void writeReference(ReferencePtr ref, AgObjectPtr value);
    int getListenerCount();
    std::map<ReferenceListenerPtr, ReferencePtr> getListeners();
    void addReferenceListener(ReferencePtr ref, ReferenceListenerPtr listener);
    void removeReferenceListener(ReferenceListenerPtr listener);
    bool isLocalReference(ReferencePtr ref);

protected:
    void processBindings(const AgString & field, int record, bool startup);
    virtual ReferenceWriterPtr getExternalReferenceWriter() = 0;
    virtual void callReferenceChanged(ReferencePtr cause, int method, ReferenceListenerPtr listener) = 0;
    virtual void setEnabled(AgObjectPtr value, int row, const AgString & field) = 0;
    virtual void setCellValue(AgObjectPtr value, int row, const AgString & field) = 0;
    virtual void setOptions(AgObjectPtr value, int row, const AgString & field) = 0;
    virtual void setSelectionValues(AgObjectPtr value, int row, const AgString & field) = 0;
    virtual void setHidden(AgObjectPtr value, int row, const AgString & field) = 0;
    virtual void setEditorEnabled(bool enabled) = 0;

};
