//----------------------------------------------------------------------------
int CDotSceneSerializer::RecurseReadObjects(TiXmlElement *parentelement,CBaseEditor* parentobject)
{
    CBaseEditor *newobj;
    TiXmlElement* element = 0;
    Ogre::String eType;
    element = parentelement->FirstChildElement();
    if(!element) return SCF_OK;
    do
    {
        newobj = 0;
        eType = element->Value();
        if(eType == "node") 
        {
            ReadSceneNode(element, parentobject, &newobj);
            int ret = RecurseReadObjects(element, newobj);
            
            if(ret != SCF_OK) 
                return ret;

            NameObjectPairList& childlist = newobj->getChildren();
            if(childlist.size() == 1)
            {
                CBaseEditor *childobj = childlist.begin()->second;
                childobj->setParent(newobj->getParent());
                OgitorsPropertyValueMap vmapn = newobj->getProperties()->getValueMap();
                OgitorsPropertyValueMap vmapo;

                OgitorsPropertyValueMap::iterator vit;

                vit = vmapn.find("autotracktarget");
                vmapo.insert(OgitorsPropertyValueMap::value_type(vit->first, vit->second));
                vit = vmapn.find("position");
                vmapo.insert(OgitorsPropertyValueMap::value_type(vit->first, vit->second));
                vit = vmapn.find("scale");
                vmapo.insert(OgitorsPropertyValueMap::value_type(vit->first, vit->second));
                vit = vmapn.find("orientation");
                vmapo.insert(OgitorsPropertyValueMap::value_type(vit->first, vit->second));

                OgitorsRoot::getSingletonPtr()->DestroyEditorObject(newobj);
                newobj = childobj;
                childobj->getProperties()->setValueMap(vmapo);
            }
        }
        else if(eType == "entity") ReadEntity(element, parentobject, &newobj);
        else if(eType == "subentities") ReadSubEntity(element, parentobject, &newobj);
        else if(eType == "light") ReadLight(element, parentobject, &newobj);
        else if(eType == "camera") ReadCamera(element, parentobject, &newobj);
        else if(eType == "particle") ReadParticle(element, parentobject, &newobj);
        else if(eType == "plane") ReadPlane(element, parentobject, &newobj);
        else 
            continue;
    } while(element = element->NextSiblingElement());
    return SCF_OK;
}
//----------------------------------------------------------------------------------
bool OgitorsClipboardManager::copyToTemplateMulti(CMultiSelEditor *object, const Ogre::String& templatename, bool isGeneralScope)
{
    if(templatename.empty())
        return false;

    NameObjectPairList list = object->getSelection();
    NameObjectPairList::iterator oit = list.begin();

    if(oit == list.end())
        return false;

    Ogre::String filename;

    OFS::OfsPtr& mFile = OgitorsRoot::getSingletonPtr()->GetProjectFile();

    if(isGeneralScope)
    {
        filename = OgitorsSystem::getSingletonPtr()->getProjectsDirectory() + "/Templates";
        filename = OgitorsUtils::QualifyPath(filename) + "/";
        OgitorsSystem::getSingletonPtr()->MakeDirectory(filename);
    }
    else
    {
        filename = "/Templates";
        mFile->createDirectory(filename.c_str());
    }
    
    
    filename += "/" + templatename + ".otl";

    std::stringstream outfile;
    outfile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    outfile << "<TEMPLATES>\n";
    outfile << "  <OBJECTTEMPLATE name=\"";
    outfile << templatename.c_str();
    outfile << "\">\n";

    ObjectTemplateMap::iterator rit;
    if(isGeneralScope)
        rit = mGeneralTemplates.insert(ObjectTemplateMap::value_type(templatename, ObjectTemplate())).first;
    else
        rit = mProjectTemplates.insert(ObjectTemplateMap::value_type(templatename, ObjectTemplate())).first;

    std::vector<CBaseEditor*> objList;

    while(oit != list.end())
    {
        CBaseEditor *item = oit->second;
        if(!item->supports(CAN_ACCEPTCOPY))
        {
            list.erase(oit);
            oit = list.begin();
        }
        else
        {
            CBaseEditor *itemParent = item->getParent();
            Ogre::String parentName = "";
            if(itemParent)
                parentName = itemParent->getName();

            if(list.find(parentName) == list.end())
            {
                list.erase(oit);
                oit = list.begin();
                objList.push_back(item);
            }
            else
                oit++;
        }
    }

    for(unsigned int objn = 0;objn < objList.size();objn++)
    {
        CBaseEditor *item = objList[objn];

        outfile << OgitorsUtils::GetObjectSaveStringV2(item, 2, false, true).c_str();

        rit->second.push_back(ObjectTemplateData());
        int itempos = rit->second.size() - 1;
        item->getPropertyMap(rit->second[itempos].mObjectProperties);
        rit->second[itempos].mObjectProperties.erase(rit->second[itempos].mObjectProperties.find("object_id"));
        OgitorsPropertyValue parentnodevalue;
        parentnodevalue.propType = PROP_STRING;
        parentnodevalue.val = Ogre::Any(item->getParent()->getName());
        rit->second[itempos].mObjectProperties.insert(OgitorsPropertyValueMap::value_type("parentnode", parentnodevalue));
        OgitorsCustomPropertySet *tmpset = OGRE_NEW OgitorsCustomPropertySet();
        item->getCustomProperties()->cloneSet(*tmpset);
        rit->second[itempos].mCustomProperties = tmpset;
        rit->second[itempos].mTypeName = item->getTypeName();
    }

    outfile << "  </OBJECTTEMPLATE>\n";
    outfile << "</TEMPLATES>\n";

    if(isGeneralScope)
    {
        std::ofstream out_general(filename.c_str());
        out_general << outfile.str();
        out_general.close();
    }
    else
    {
        OgitorsUtils::SaveStreamOfs(outfile, filename);
    }

    return true;
}
//----------------------------------------------------------------------------------
bool OgitorsClipboardManager::copyToTemplateWithChildren(CBaseEditor *object, const Ogre::String& templatename, bool isGeneralScope)
{
    if(templatename.empty())
        return false;

    Ogre::String filename;
    OFS::OfsPtr& mFile = OgitorsRoot::getSingletonPtr()->GetProjectFile();
    
    if(isGeneralScope)
    {
        filename = OgitorsSystem::getSingletonPtr()->getProjectsDirectory() + "/Templates";
        filename = OgitorsUtils::QualifyPath(filename);
        OgitorsSystem::getSingletonPtr()->MakeDirectory(filename);
    }
    else
    {
        filename = "/Templates";
        mFile->createDirectory(filename.c_str());
    }
    
    
    filename += "/" + templatename + ".otl";

    std::stringstream outfile;
    outfile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    outfile << "<TEMPLATES>\n";
    outfile << "  <OBJECTTEMPLATE name=\"";
    outfile << templatename.c_str();
    outfile << "\">\n";
    Ogre::StringVector list;
    object->getNameList(list);
    outfile << OgitorsUtils::GetObjectSaveStringV2(object, 4, false, false).c_str();

    ObjectTemplateMap::iterator rit;
    if(isGeneralScope)
        rit = mGeneralTemplates.insert(ObjectTemplateMap::value_type(templatename, ObjectTemplate())).first;
    else
        rit = mProjectTemplates.insert(ObjectTemplateMap::value_type(templatename, ObjectTemplate())).first;

    rit->second.push_back(ObjectTemplateData());
    object->getPropertyMap(rit->second[0].mObjectProperties);
    rit->second[0].mObjectProperties.erase(rit->second[0].mObjectProperties.find("object_id"));
    OgitorsCustomPropertySet *tmpset = OGRE_NEW OgitorsCustomPropertySet();
    object->getCustomProperties()->cloneSet(*tmpset);
    rit->second[0].mCustomProperties = tmpset;
    rit->second[0].mTypeName = object->getTypeName();

    for(unsigned int i = 1;i < list.size();i++)
    {
        CBaseEditor *item = OgitorsRoot::getSingletonPtr()->FindObject(list[i]);
        if(item != 0)
        {
            outfile << OgitorsUtils::GetObjectSaveStringV2(item, 4, false, true).c_str();

            rit->second.push_back(ObjectTemplateData());
            int itempos = rit->second.size() - 1;
            item->getPropertyMap(rit->second[itempos].mObjectProperties);
            rit->second[itempos].mObjectProperties.erase(rit->second[itempos].mObjectProperties.find("object_id"));
            OgitorsPropertyValue parentnodevalue;
            parentnodevalue.propType = PROP_STRING;
            parentnodevalue.val = Ogre::Any(item->getParent()->getName());
            rit->second[itempos].mObjectProperties.insert(OgitorsPropertyValueMap::value_type("parentnode", parentnodevalue));
            OgitorsCustomPropertySet *tmpset = OGRE_NEW OgitorsCustomPropertySet();
            item->getCustomProperties()->cloneSet(*tmpset);
            rit->second[itempos].mCustomProperties = tmpset;
            rit->second[itempos].mTypeName = item->getTypeName();
        }
    }
    
    outfile << "  </OBJECTTEMPLATE>\n";
    outfile << "</TEMPLATES>\n";

    if(isGeneralScope)
    {
        std::ofstream out_general(filename.c_str());
        out_general << outfile.str();
        out_general.close();
    }
    else
    {
        OgitorsUtils::SaveStreamOfs(outfile, filename);
    }

    return true;
}