Index: orxonox/trunk/src/lib/util/resource_manager.cc
===================================================================
--- orxonox/trunk/src/lib/util/resource_manager.cc	(revision 3657)
+++ orxonox/trunk/src/lib/util/resource_manager.cc	(revision 3658)
@@ -23,4 +23,6 @@
 #include "texture.h"
 
+#include "list.h"
+
 // File Handling Includes
 #include <sys/types.h>
@@ -28,8 +30,6 @@
 #include <unistd.h>
 
-
 using namespace std;
 
-
 /**
    \brief standard constructor
@@ -38,5 +38,7 @@
 {
    this->setClassName ("ResourceManager");
-   this->dataDir = NULL;
+   dataDir = NULL;
+   imageDirs = new tList<char>();
+   resourceList = new tList<Resource>();
 }
 
@@ -48,5 +50,12 @@
 }
 
+//! Singleton Reference to the ResourceManager
 ResourceManager* ResourceManager::singletonRef = NULL;
+//! The List of Resources, that has already been loaded.
+tList<Resource>* ResourceManager::resourceList = NULL;
+//! The Data Directory, where all relevant Data is stored.
+char* ResourceManager::dataDir = NULL;
+//! A list of directories in which images are stored.
+tList<char>* ResourceManager::imageDirs = NULL;
 
 /**
@@ -55,8 +64,9 @@
 ResourceManager::~ResourceManager (void) 
 {
+
+  delete resourceList;
+  resourceList = NULL;
   ResourceManager::singletonRef = NULL;
 }
-
-
 
 /**
@@ -68,10 +78,24 @@
   if (isDir(dataDir))
     {
-      this->dataDir = new char[strlen(dataDir)+1];
-      strcpy(this->dataDir, dataDir);
+      ResourceManager::dataDir = new char[strlen(dataDir)+1];
+      strcpy(ResourceManager::dataDir, dataDir);
     }
   else
     {
       PRINTF(1)("%s is not a Directory, and can not be the Data Directory\n", dataDir);
+    }
+}
+
+bool ResourceManager::addImageDir(char* imageDir)
+{
+  if (isDir(imageDir))
+    {
+      char* tmpDir  = new char[strlen(imageDir)+1];
+      strcpy(tmpDir, imageDir);
+      imageDirs->add(tmpDir);
+    }
+  else
+    {
+      PRINTF(1)("%s is not a Directory, and can not be added to the Paths of Images\n", dataDir);
     }
 }
@@ -87,4 +111,18 @@
   if (!strncmp(fileName+(strlen(fileName)-4), ".obj", 4))
     tmpType = OBJ;
+  else if (!strncmp(fileName+(strlen(fileName)-4), ".wav", 4))
+    tmpType = WAV;
+  else if (!strncmp(fileName+(strlen(fileName)-4), ".mp3", 4))
+    tmpType = MP3;
+  else if (!strncmp(fileName+(strlen(fileName)-4), ".ogg", 4))
+    tmpType = OGG;
+  else if (!strcmp(fileName, "cube") ||
+           !strcmp(fileName, "sphere") ||
+	   !strcmp(fileName, "plane") ||
+           !strcmp(fileName, "cylinder") ||
+           !strcmp(fileName, "cone"))
+    tmpType = PRIM;
+  else 
+    tmpType = IMAGE;
 
   return ResourceManager::load(fileName, tmpType);
@@ -99,40 +137,164 @@
 void* ResourceManager::load(const char* fileName, ResourceType type)
 {
-  void* tmpResource = NULL;
-  char* tmpName = new char[strlen(fileName)+1];
-  strcpy(tmpName, fileName);
-  // Checking for the type of resource \see ResourceType
-  switch(type)
-    {
-    case OBJ:
-      if(isFile(tmpName))
-	tmpResource = new OBJModel(tmpName);
-      else
+  // searching if the resource was loaded before.
+  Resource* tmpResource = ResourceManager::locateResourceByName(fileName);
+  char* tmpDir;
+  if (!tmpResource) // if the resource was not loaded before.
+    {
+      // Setting up the new Resource
+      tmpResource = new Resource;
+      tmpResource->count = 1;
+      tmpResource->type = type;
+      tmpResource->name = new char[strlen(fileName)+1];
+      strcpy(tmpResource->name, fileName);
+
+      // creating the full name. (directoryName + FileName)
+      char* fullName = new char[strlen(dataDir)+strlen(fileName)+1];
+      sprintf(fullName, "%s%s", dataDir, fileName);
+      
+      // Checking for the type of resource \see ResourceType
+      switch(type)
 	{
-	  PRINTF(2)("Sorry, %s does not exist. Loading a cube-Model instead\n", tmpName);
-	  tmpResource = new PrimitiveModel(CUBE);
+	case OBJ:
+	  if(isFile(fullName))
+	    tmpResource->pointer = new OBJModel(fullName);
+	  else
+	    {
+	      PRINTF(2)("Sorry, %s does not exist. Loading a cube-Model instead\n", fullName);
+	      tmpResource->pointer = ResourceManager::load("cube", PRIM);
+	    }
+	  break;
+	case PRIM:
+	  if (!strcmp(tmpResource->name, "cube"))
+	    tmpResource->pointer = new PrimitiveModel(CUBE);
+	  else if (!strcmp(tmpResource->name, "sphere"))
+	    tmpResource->pointer = new PrimitiveModel(SPHERE);
+	  else if (!strcmp(tmpResource->name, "plane"))
+	    tmpResource->pointer = new PrimitiveModel(PLANE);
+	  else if (!strcmp(tmpResource->name, "cylinder"))
+	    tmpResource->pointer = new PrimitiveModel(CYLINDER);
+	  else if (!strcmp(tmpResource->name, "cone"))
+	    tmpResource->pointer = new PrimitiveModel(CONE);
+	  break;
+	case IMAGE:
+	  if(isFile(fullName))
+	    {
+	      tmpResource->pointer = new Texture(fullName);
+	    }
+	  else
+	    {
+	      tmpDir = imageDirs->enumerate();
+	      while(tmpDir)
+		{
+		  char* imgName = new char[strlen(tmpDir)+strlen(fileName)+1];
+		  sprintf(imgName, "%s%s", tmpDir, fileName);
+		  if(isFile(imgName))
+		    tmpResource->pointer = new Texture(imgName);
+		  delete []imgName;
+		  tmpDir = imageDirs->nextElement();
+		}
+	    }
+	  if(!tmpResource)
+	     PRINTF(2)("!!Image %s not Found!!\n", fileName);
+	  break;
+	default:
+	  tmpResource->pointer = NULL;
+	  PRINTF(1)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet.!!\n", tmpResource->name);
+	  break;
 	}
-      break;
-    case IMAGE:
-      if(isFile(tmpName))
+      
+      // checking if the File really exists.
+      if(!isFile(fullName))
 	{
-	  tmpResource = new Texture(tmpName);
+	  PRINTF(2)("Sorry, %s is not a regular file.\n", fullName);
+	  tmpResource->pointer = NULL;
 	}
-      else
-	PRINTF(1)("!!Texture %s not Found!!\n", tmpName);
-      break;
-    default:
-      tmpResource = NULL;
-      PRINTF(2)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet.!!\n", tmpName);
-      break;
-    }
-
-  // checking if the File really exists.
-  if(!isFile(tmpName))
-    {
-      PRINTF(2)("Sorry, %s is not a regular file.\n", tmpName);
-      tmpResource = NULL;
-    }
-  return tmpResource;
+      resourceList->add(tmpResource);
+      delete []fullName;
+
+    }
+  else
+    {
+      tmpResource->count++;
+    }
+
+  return tmpResource->pointer;
+}
+
+/**
+   \brief unloads a Resource
+   \param pointer The pointer to free
+   \returns true if successful (pointer found, and deleted), false otherwise
+   
+*/
+bool ResourceManager::unload(void* pointer)
+{
+  // if pointer is existent. and only one resource of this type exists.
+  Resource* tmpResource = ResourceManager::locateResourceByPointer(pointer);
+  if (!tmpResource)
+    {
+      PRINTF(2)("Resource not Found %p\n", pointer);
+      return false;
+    }
+  tmpResource->count--;
+  if (tmpResource->count <= 0)
+    {
+      // deleting the Resource
+      switch(tmpResource->type)
+	{
+	case OBJ:
+	case PRIM:
+	  delete (Model*)tmpResource->pointer;
+	  break;
+	case IMAGE:
+	  delete (Texture*)tmpResource->pointer;
+	  break;
+	default:
+	  PRINTF(1)("NOT YET IMPLEMENTED FIX FIX\n");
+	  return false;
+	  break;
+	}
+      // deleting the List Entry:
+      PRINTF(4)("Resource %s Safely removed.\n", tmpResource->name);
+      delete []tmpResource->name;
+      resourceList->remove(tmpResource);
+    }
+  else
+    PRINTF(4)("Resource not removed, because there are still %d References to it.\n", tmpResource->count);
+  return true;
+}
+
+/**
+   \brief Searches for a Resource by Name
+   \param fileName The name to look for
+   \returns a Pointer to the Resource if found, NULL otherwise.
+*/
+Resource* ResourceManager::locateResourceByName(const char* fileName)
+{
+  Resource* enumRes = resourceList->enumerate();
+  while (enumRes)
+    {
+      if (!strcmp(fileName, enumRes->name))
+	return enumRes;
+      enumRes = resourceList->nextElement();
+    }
+  return NULL;
+}
+
+/**
+   \brief Searches for a Resource by Pointer
+   \param pointer the Pointer to search for
+   \returns a Pointer to the Resource if found, NULL otherwise.
+*/
+Resource* ResourceManager::locateResourceByPointer(const void* pointer)
+{
+  Resource* enumRes = resourceList->enumerate();
+  while (enumRes)
+    {
+      if (pointer == enumRes->pointer);
+	return enumRes;
+      enumRes = resourceList->nextElement();
+    }
+  return NULL;
 }
 
@@ -148,5 +310,5 @@
   if (status.st_mode & (S_IFDIR | S_IFLNK))
     return true;
-  else 
+  else
     return false;
 }
Index: orxonox/trunk/src/lib/util/resource_manager.h
===================================================================
--- orxonox/trunk/src/lib/util/resource_manager.h	(revision 3657)
+++ orxonox/trunk/src/lib/util/resource_manager.h	(revision 3658)
@@ -15,7 +15,17 @@
 
 // FORWARD DEFINITION \\
+//template<class T> class tList;
+#include "list.h"                //! \todo do this by forward definition (ask Patrick)
+enum ResourceType {OBJ, PRIM, WAV, MP3, OGG, IMAGE};
 
+struct Resource
+{
+  void* pointer;             //!< Pointer to the Resource.
+  
+  char* name;                //!< Name of the Resource.
+  ResourceType type;         //!< ResourceType of this Resource.
+  int count;                 //!< How many times this Resource has been loaded.
+};
 
-enum ResourceType {OBJ, WAV, MP3, OGG, IMAGE};
 
 //! The ResourceManager is a class, that decides if a file/resource should be loaded
@@ -34,7 +44,9 @@
   virtual ~ResourceManager();
 
-  bool setDataDir(char* dataDir);
+  static bool setDataDir(char* dataDir);
+  static bool addImageDir(char* imageDir);
   static void* load(const char* fileName);
   static void* load(const char* fileName, ResourceType type);
+  static bool unload(void* pointer);
 
  private:
@@ -42,19 +54,11 @@
   static ResourceManager* singletonRef;
 
+  static tList<Resource>* resourceList;
+  static char* dataDir;
+  static tList<char>* imageDirs;
 
-  struct file;
-  struct folder
-  {
-    char* name;
-    folder** subfolders;             //!< 
-    file** files;                    //!< Files in the directory
-  };
-  struct file
-  {
-    char* name;                      //!< exact Name of a file
-    void* pointer;
-  };
-
-  char* dataDir;                     //!< The main data directory
+  static Resource* locateResourceByName(const char* fileName);
+  static Resource* locateResourceByPointer(const void* pointer);
+  
 
   static bool isDir(const char* directory);
