void BoolFieldEditor::runCommand  (bool value)
{
    bool fieldValue;
    GetFieldHandlePtr TheFieldHandle = getEditingFC()->getField(getEditingFieldId());

    if(TheFieldHandle->getCardinality() == FieldType::SingleField)
    {
        fieldValue = static_cast<const SFBool*>(TheFieldHandle->getField())->getValue();
    }
    else
    {
        fieldValue = static_cast<const MFBool*>(TheFieldHandle->getField())->operator[](getEditingFieldIndex());
    }

    if(value != fieldValue)
    {
        //Call the command to set the Field
        SetFieldValueCommandPtr SetCommand = SetFieldValueCommand::create(getEditingFC(), 
                                                                          getEditingFieldId(), 
                                                                          (value ? "TRUE" : "FALSE"), 
                                                                          getEditingFieldIndex());

        getCommandManager()->executeCommand(SetCommand);
    }
}
bool GenericFieldContainerEditor::attachFieldContainer(FieldContainer* fc)
{
    //Check that this is a valid FieldContainer
    if(!Inherited::attachFieldContainer(fc))
    {
        return false;
    }

    dettachFieldContainer();

    //Update the Type and Id Labels
    _ContainerTypeLabel->setText(getEditingFC()->getType().getName());

    ComponentRecPtr TheToolTip = createFCToolTip(getEditingFC()->getType());
    _ContainerTypeLabel->setToolTip(TheToolTip);

    _ContainerIdLabel->setText(boost::lexical_cast<std::string>(getEditingFC()->getId()));

    //Create the Fields Panel
    updateFieldsPanel(fc);
    
    //Create the ProducedEvents Panel
    updateProducedEventsPanel(fc);


    //Tell my parent to update my size
    editSField(PreferredSizeFieldMask);

    return true;
}
void FieldEditorComponent::fieldChanged(FieldContainer *fc, ConstFieldMaskArg whichField)
{
    if(fc == getEditingFC() &&
       (whichField & getEditingFC()->getFieldDescription(getEditingFieldId())->getFieldMask()))
    {
        internalFieldChanged();
    }
}
void TextFieldEditor::internalStopEditing  (void)
{
    //Call the command to set the Field
    SetFieldValueCommandPtr SetCommand = SetFieldValueCommand::create(getEditingFC(), getEditingFieldId(), _EditingTextArea->getText(), getEditingFieldIndex());

    getCommandManager()->executeCommand(SetCommand);
}
void FCPtrFieldEditor::internalStopEditing  (void)
{
    std::string FCId(_EditingTextField->getText());
    if(_EditingTextField->getText().compare("NULL") == 0)
    {
        FCId = "0";
    }
    else
    {
        //Make sure the Id can be cast to a UInt32
        try
        {
            UInt32 CastTest = boost::lexical_cast<UInt32>(FCId);
        }
        catch(boost::bad_lexical_cast &)
        {
            //If it can't then cancel editing
            internalCancelEditing();
            return;
        }
    }

    //Call the command to set the Field
    SetFieldValueCommandPtr SetCommand = SetFieldValueCommand::create(getEditingFC(), getEditingFieldId(), FCId, getEditingFieldIndex());

    getCommandManager()->executeCommand(SetCommand);
}
/***************************************************************************\
 *                           Instance methods                              *
\***************************************************************************/
void BoolFieldEditor::internalFieldChanged (void)
{

    GetFieldHandlePtr TheFieldHandle = getEditingFC()->getField(getEditingFieldId());
    bool Value;

    if(TheFieldHandle->getCardinality() == FieldType::SingleField)
    {
        Value = static_cast<const SFBool*>(TheFieldHandle->getField())->getValue();
    }
    else
    {
        Value = static_cast<const MFBool*>(TheFieldHandle->getField())->operator[](getEditingFieldIndex());
    }

    if(_EditingCheckbox->getSelected() != Value)
    {
        _ButtonSelectedConnection.disconnect();
        _ButtonDeselectedConnection.disconnect();

        _EditingCheckbox->setSelected(Value);
    }

    _ButtonSelectedConnection = _EditingCheckbox->connectButtonSelected(boost::bind(&BoolFieldEditor::handleButtonSelected, this, _1));
    _ButtonDeselectedConnection = _EditingCheckbox->connectButtonDeselected(boost::bind(&BoolFieldEditor::handleButtonDeselected, this, _1));

}
/***************************************************************************\
 *                           Instance methods                              *
\***************************************************************************/
void GenericFieldEditor::internalFieldChanged (void)
{
    GetFieldHandlePtr TheFieldHandle = getEditingFC()->getField(getEditingFieldId());

    if(TheFieldHandle->isPointerField())
    {
        if(TheFieldHandle->getCardinality() == FieldType::SingleField)
        {
            GetSFieldHandle<FieldContainerPtrSFieldBase>* ThePtrFieldHandle(dynamic_cast<GetSFieldHandle<FieldContainerPtrSFieldBase>*>(TheFieldHandle.get()));
            if(ThePtrFieldHandle->get() != NULL)
            {
                _EditingTextField->setText(boost::lexical_cast<std::string>(ThePtrFieldHandle->get()->getId()));
            }
            else
            {
                _EditingTextField->setText("0");
            }
        }
        else
        {
            GetMFieldHandle<FieldContainerPtrMFieldBase>* ThePtrFieldHandle(dynamic_cast<GetMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
            if(ThePtrFieldHandle->size() > getEditingFieldIndex() &&
               ThePtrFieldHandle->get(getEditingFieldIndex()) != NULL)
            {
                _EditingTextField->setText(boost::lexical_cast<std::string>(ThePtrFieldHandle->get(getEditingFieldIndex())->getId()));
            }
            else
            {
                _EditingTextField->setText("0");
            }
        }
    }
    else
    {
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);
        if(TheFieldHandle->getCardinality() == FieldType::SingleField)
        {
            TheFieldHandle->pushValueToStream(TheOutStream);
        }
        else
        {
            TheFieldHandle->pushIndexedValueToStream(TheOutStream, getEditingFieldIndex());
        }

        //Remove quotes from strings
        if(TheFieldHandle->getType().getContentType() == FieldTraits<std::string>::getType())
        {
            _EditingTextField->setText(StrStream.str().substr(1,StrStream.str().size()-2));
        }
        else
        {
            _EditingTextField->setText(StrStream.str());
        }
    }

}
void ImageFieldEditor::openCreateHandler(void)
{
    //Have the user select the file to import
    std::vector<WindowEventProducer::FileDialogFilter> Filters;

    std::list< const Char8 * > ReadableImageSuff;
    ImageFileHandler::the()->getSuffixList(ReadableImageSuff, ImageFileType::OSG_READ_SUPPORTED);
    //Determine all of the readable image filetypes
    Filters.push_back(WindowEventProducer::FileDialogFilter("All Image filetypes",""));
    std::string AllImageSuffixes;
    std::string AllImageSuffixesDesc("All Image filetypes (");
    for(std::list<const Char8*>::const_iterator SuffixItor(ReadableImageSuff.begin()) ; SuffixItor != ReadableImageSuff.end() ; ++SuffixItor)
    {
        if(ImageFileHandler::the()->getFileType(*SuffixItor))
        {
            if(!AllImageSuffixes.empty())
            {
                AllImageSuffixes += ",";
                AllImageSuffixesDesc += ", ";
            }
            AllImageSuffixes += *SuffixItor;
            AllImageSuffixesDesc = AllImageSuffixesDesc + "*." + *SuffixItor;
            Filters.push_back(WindowEventProducer::FileDialogFilter(std::string(ImageFileHandler::the()->getFileType(*SuffixItor)->getMimeType()) +  " (*." + *SuffixItor + ")",*SuffixItor));
        }
    }
    AllImageSuffixesDesc += ")";
    Filters[0] = WindowEventProducer::FileDialogFilter(AllImageSuffixesDesc,AllImageSuffixes);
    Filters.push_back(WindowEventProducer::FileDialogFilter("All (*.*)","*"));

    std::vector<BoostPath> FilesToOpen;
    FilesToOpen = getParentWindow()->getParentDrawingSurface()->getEventProducer()->openFileDialog("Import a image file.",
                                                                          Filters,
                                                                          BoostPath("."),
                                                                          false);

    ImageRefPtr NewImage = NULL;

    if(FilesToOpen.size() > 0)
    {
        //Try loading the file using the ImageFileHandler
        NewImage = ImageFileHandler::the()->read(FilesToOpen[0].string().c_str());

        if(NewImage)
        {
            FilePathAttachment::setFilePath(NewImage, FilesToOpen[0]);

            //Set the value of the field
            SetFieldValueCommandPtr SetCommand =
                SetFieldValueCommand::create(getEditingFC(),
                                             getEditingFieldId(),
                                             boost::lexical_cast<std::string>(NewImage->getId()),
                                             getEditingFieldIndex());

            getCommandManager()->executeCommand(SetCommand);
        }
    }
}
void FCPtrFieldEditor::handleCreateContainerDialogClosed(DialogWindowEventDetails* const details)
{
    if(details->getOption() != DialogWindowEventDetails::DIALOG_OPTION_CANCEL)
    {
        const FieldContainerType* ThePtrType(getFieldContainerTypeFromPtrType(getEditingFC()->getFieldDescription(getEditingFieldId())->getFieldType().getContentType()));

        const FieldContainerType* TheType(FieldContainerFactory::the()->findType(details->getInput().c_str()));

        if(TheType != NULL)
        {
            //Create the Container
            CreateFieldContainerCommandPtr CreateCommand;
            
            //If the type is a node, then create a NodeCore instead
            //and then insert it as the core of a newly created node
            if(*ThePtrType == Node::getClassType())
            {
                CreateFieldContainerCommandPtr CreateCoreCommand = CreateFieldContainerCommand::create(TheType);
                getCommandManager()->executeCommand(CreateCoreCommand);
                
                CreateCommand = CreateFieldContainerCommand::create(&Node::getClassType());
                getCommandManager()->executeCommand(CreateCommand);

                dynamic_cast<Node*>(CreateCommand->getContainer())->setCore(dynamic_cast<NodeCore*>(CreateCoreCommand->getContainer()));
            }
            else
            {
                CreateCommand = CreateFieldContainerCommand::create(TheType);
                getCommandManager()->executeCommand(CreateCommand);
            }

            //Set the value of the field
            SetFieldValueCommandPtr SetCommand =
                SetFieldValueCommand::create(getEditingFC(),
                                             getEditingFieldId(),
                                             boost::lexical_cast<std::string>(CreateCommand->getContainer()->getId()),
                                             getEditingFieldIndex());

            getCommandManager()->executeCommand(SetCommand);
        }
    }
    _CreateContainerDialogClosedConnection.disconnect();
}
bool GenericFieldContainerEditor::dettachFieldContainer(void)
{
    //Dettach the Name Editor
    if(getEditingFC() &&
       _GenericNameAttachmentEditor->isTypeEditable(getEditingFC()->getType()))
    {
        _GenericNameAttachmentEditor->dettachContainer();
    }

    //Clear Children
    clearEditors();

    _FieldsContainer->clearChildren();
    _ProducedEventsContainer->clearChildren();

    //Set the number of rows for the grid layout
    dynamic_cast<GridBagLayout*>(_FieldsContainer->getLayout())->setRows(0);
    dynamic_cast<GridLayout*>(_ProducedEventsContainer->getLayout())->setRows(0);

    return Inherited::dettachFieldContainer();
}
void GenericMultiFieldEditor::handleListMouseClicked(MouseEventDetails* const details)
{
    if(details->getButton() == MouseEventDetails::BUTTON1 && 
       details->getClickCount() == 1 &&
       _FieldList->getIndexForDrawingSurfaceLocation(details->getLocation()) == -1)
    {
        insertAtIndex(getEditingFC(),
                      getEditingFieldId(),
                      //Size of list,
                      _FieldList->getModel()->getSize(),
                      getParentWindow()->getParentDrawingSurface(),
                      getCommandManager().get());
    }
}
void FCPtrFieldEditor::handleFindContainerDialogClosed(DialogWindowEventDetails* const details)
{
    if(details->getOption() != DialogWindowEventDetails::DIALOG_OPTION_CANCEL)
    {
        FCPtrEditorStore::FieldContianerVector fcStore(_FindFCStore->getList());
        //Set the value of the field
        SetFieldValueCommandPtr SetCommand =
            SetFieldValueCommand::create(getEditingFC(),
                                         getEditingFieldId(),
                                         boost::lexical_cast<std::string>(fcStore[details->getInputIndex()]->getId()),
                                         getEditingFieldIndex());

        getCommandManager()->executeCommand(SetCommand);
    }
    _FindContainerDialogClosedConnection.disconnect();
}
void FCPtrFieldEditor::openCreateHandler(void)
{
    const FieldContainerType* ThePtrType(getFieldContainerTypeFromPtrType(getEditingFC()->getFieldDescription(getEditingFieldId())->getFieldType().getContentType()));
    if(ThePtrType == NULL)
    {
        return;
    }

    //If the type is a node, then create a NodeCore instead
    //and then insert it as the core of a newly created node
    if(*ThePtrType == Node::getClassType())
    {
        ThePtrType = &NodeCore::getClassType();
    }

    std::vector<std::string> inputValues;
    UInt32 NumFieldContainersFound(0);
    const FieldContainerType* FoundType(NULL);
    for(UInt32 j(0) ; NumFieldContainersFound<FieldContainerFactory::the()->getNumTypes(); ++j)
    {
        FoundType = FieldContainerFactory::the()->findType(j);
        if(FoundType != NULL)
        {
            if(FoundType->isDerivedFrom(*ThePtrType)  && !FoundType->isAbstract())
            {
                inputValues.push_back(FoundType->getName());
            }
            ++NumFieldContainersFound;
        }
    }

    DialogWindowRefPtr TheDialog = DialogWindow::createInputDialog("Create Field Container",
                                                                   "Choose the type of object to create",
                                                                   DialogWindow::INPUT_COMBO,
                                                                   true,
                                                                   inputValues);
    _CreateContainerDialogClosedConnection = TheDialog->connectDialogWindowClosed(boost::bind(&FCPtrFieldEditor::handleCreateContainerDialogClosed, this, _1));

    Pnt2f CenteredPosition = calculateAlignment(Pnt2f(0.0f,0.0f), getParentWindow()->getParentDrawingSurface()->getSize(), TheDialog->getPreferredSize(), 0.5f, 0.5f);
    TheDialog->setPosition(CenteredPosition);
    TheDialog->setAllwaysOnTop(true);
    TheDialog->setModal(true);
    TheDialog->setResizable(true);

    getParentWindow()->getParentDrawingSurface()->openWindow(TheDialog);
}
void FCPtrFieldEditor::internalFieldChanged (void)
{
    GetFieldHandlePtr TheFieldHandle = getEditingFC()->getField(getEditingFieldId());

    assert(TheFieldHandle->getType().getClass() == FieldType::PtrField ||
           TheFieldHandle->getType().getClass() == FieldType::ChildPtrField);

    //Get the Editing FCPtr
    FieldContainer* EditingFC(NULL);
    if(TheFieldHandle->getCardinality() == FieldType::SingleField)
    {
        GetSFieldHandle<FieldContainerPtrSFieldBase>* ThePtrFieldHandle(dynamic_cast<GetSFieldHandle<FieldContainerPtrSFieldBase>*>(TheFieldHandle.get()));
        EditingFC = ThePtrFieldHandle->get();
    }
    else
    {
        GetMFieldHandle<FieldContainerPtrMFieldBase>* ThePtrFieldHandle(dynamic_cast<GetMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        EditingFC = ThePtrFieldHandle->get(getEditingFieldIndex());
    }

    //Update the Editing Text
    std::string EditingText("NULL");
    std::string Name("");
    std::string TypeName("");

    if(EditingFC != NULL)
    {
        //Get the Id of the FieldContainer
        EditingText = boost::lexical_cast<std::string>(EditingFC->getId());

        //If the FieldContainer has a name attachment then get the name
        if(EditingFC->getType().isDerivedFrom(AttachmentContainer::getClassType()) && 
           getName(dynamic_cast<AttachmentContainer*>(EditingFC)))
        {
            Name = getName(dynamic_cast<AttachmentContainer*>(EditingFC));
        }

        //Get the name of the type of the FieldContainer
        TypeName = EditingFC->getType().getName();
    }


    //Update the Labels and TextFields
    _EditingTextField->setText(EditingText);
    _NameTypeLabel->setText(Name + " [" + TypeName + "]");
}
void FieldContainerEditorComponent::changed(ConstFieldMaskArg whichField, 
                            UInt32            origin,
                            BitVector         details)
{
    Inherited::changed(whichField, origin, details);

    //Do not respond to changes that have a Sync origin
    if(origin & ChangedOrigin::Sync)
    {
        return;
    }
    
    if(whichField & EditingFCFieldMask)
    {
        attachFieldContainer(getEditingFC());
    }
}
void TextFieldEditor::internalFieldChanged (void)
{
    GetFieldHandlePtr TheFieldHandle = getEditingFC()->getField(getEditingFieldId());

    std::ostringstream StrStream;
    OutStream TheOutStream(StrStream);
    if(TheFieldHandle->getCardinality() == FieldType::SingleField)
    {
        TheFieldHandle->pushValueToStream(TheOutStream);
    }
    else
    {
        TheFieldHandle->pushIndexedValueToStream(TheOutStream, getEditingFieldIndex());
    }
        
    _EditingTextArea->setText(StrStream.str());

}
/***************************************************************************\
 *                           Instance methods                              *
\***************************************************************************/
bool FieldContainerEditorComponent::attachFieldContainer(FieldContainer* fc)
{
    //Check that this is a valid FieldContainer
    if(fc == NULL)
    {
        SWARNING << "Cannot attach to a Null FieldContainer." << std::endl;
        return false;
    }

    dettachFieldContainer();

    if(getEditingFC() != fc)
    {
        setEditingFC(fc);
    }

    return true;
}
void FCPtrFieldEditor::openFindContainerHandler(void)
{
    const FieldContainerType* ThePtrType(getFieldContainerTypeFromPtrType(getEditingFC()->getFieldDescription(getEditingFieldId())->getFieldType().getContentType()));
    if(ThePtrType == NULL)
    {
        return;
    }

    std::vector<std::string> inputValues;
    _FindFCStore->setTypeToStore(ThePtrType);
    FCPtrEditorStore::FieldContianerVector fcStore(_FindFCStore->getList());

    std::string value;
    for(UInt32 i(0) ; i<fcStore.size(); ++i)
    {
        value.clear();
        if(fcStore[i]->getType().isDerivedFrom(AttachmentContainer::getClassType()) &&
           getName(dynamic_pointer_cast<AttachmentContainer>(fcStore[i])))
        {
            value += std::string(getName(dynamic_pointer_cast<AttachmentContainer>(fcStore[i]))) + " ";
        }
        value += "[" + fcStore[i]->getType().getName() + "] " + boost::lexical_cast<std::string>(fcStore[i]->getId());
        inputValues.push_back(value);
    }

    DialogWindowRefPtr TheDialog = DialogWindow::createInputDialog("Find Field Container",
                                                                   "Choose the container to use",
                                                                   DialogWindow::INPUT_LIST,
                                                                   true,
                                                                   inputValues);
    _FindContainerDialogClosedConnection = TheDialog->connectDialogWindowClosed(boost::bind(&FCPtrFieldEditor::handleFindContainerDialogClosed, this, _1));

    Pnt2f CenteredPosition = calculateAlignment(Pnt2f(0.0f,0.0f), getParentWindow()->getParentDrawingSurface()->getSize(), TheDialog->getPreferredSize(), 0.5f, 0.5f);
    TheDialog->setPosition(CenteredPosition);
    TheDialog->setAllwaysOnTop(true);
    TheDialog->setResizable(true);

    getParentWindow()->getParentDrawingSurface()->openWindow(TheDialog);
}