1 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "rectangle.h"
22 #include "ucompose.hpp"
23 #include <sigc++/functors/mem_fun.h>
25 #include "tilesetlist.h"
32 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
35 Tilesetlist* Tilesetlist::s_instance = 0;
37 Tilesetlist* Tilesetlist::getInstance()
40 s_instance = new Tilesetlist();
45 void Tilesetlist::deleteInstance()
53 Tilesetlist::Tilesetlist()
57 loadTilesets(Tileset::scanSystemCollection());
58 loadTilesets(Tileset::scanUserCollection());
61 Tilesetlist::~Tilesetlist()
63 for (iterator it = begin(); it != end(); it++)
67 void Tilesetlist::getSizes(std::list<guint32> &sizes) const
69 for (const_iterator i = begin(); i != end(); i++)
71 if (find (sizes.begin(), sizes.end(), (*i)->getTileSize()) == sizes.end())
72 sizes.push_back((*i)->getTileSize());
76 std::list<std::string> Tilesetlist::getNames() const
78 std::list<std::string> names;
79 for (const_iterator it = begin(); it != end(); it++)
80 names.push_back((*it)->getName());
84 std::list<std::string> Tilesetlist::getNames(guint32 tilesize) const
86 std::list<std::string> names;
87 for (const_iterator it = begin(); it != end(); it++)
88 if ((*it)->getTileSize() == tilesize)
89 names.push_back((*it)->getName());
93 Tileset *Tilesetlist::loadTileset(std::string filename)
95 debug("Loading tileset " <<File::get_basename(File::get_dirname(filename)));
96 Tileset *tileset = Tileset::create(filename);
99 if (tileset->validate() == false)
101 cerr<< "Error! Tileset: `" << tileset->getConfigurationFile() <<
102 "' fails validation. Skipping.\n",
106 if (d_tilesetids.find(tileset->getId()) != d_tilesetids.end())
108 Tileset *t = (*d_tilesetids.find(tileset->getId())).second;
109 cerr << "Error! tileset: `" << tileset->getName() <<
110 "' shares a duplicate tileset id with `" <<
111 t->getConfigurationFile() << "'. Skipping." << endl;
118 void Tilesetlist::add(Tileset *tileset)
120 std::string subdir = File::get_basename(tileset->getDirectory());
122 tileset->setSubDir(subdir);
123 d_dirs[String::ucompose("%1 %2", tileset->getName(), tileset->getTileSize())] = subdir;
124 d_tilesets[subdir] = tileset;
125 d_tilesetids[tileset->getId()] = tileset;
128 std::string Tilesetlist::getTilesetDir(std::string name, guint32 tilesize) const
130 DirMap::const_iterator it = d_dirs.find(String::ucompose("%1 %2", name, tilesize));
131 if (it == d_dirs.end())
137 void Tilesetlist::loadTilesets(std::list<std::string> tilesets)
139 for (std::list<std::string>::const_iterator i = tilesets.begin();
140 i != tilesets.end(); i++)
142 Tileset *tileset = loadTileset(*i);
149 int Tilesetlist::getNextAvailableId(int after)
151 std::list<guint32> ids;
152 std::list<std::string> tilesets = Tileset::scanSystemCollection();
153 //there might be IDs in invalid tilesets.
154 for (std::list<std::string>::const_iterator i = tilesets.begin();
155 i != tilesets.end(); i++)
157 Tileset *tileset = Tileset::create(*i);
160 ids.push_back(tileset->getId());
164 tilesets = Tileset::scanUserCollection();
165 for (std::list<std::string>::const_iterator i = tilesets.begin();
166 i != tilesets.end(); i++)
168 Tileset *tileset = Tileset::create(*i);
171 ids.push_back(tileset->getId());
175 for (guint32 i = after + 1; i < 1000000; i++)
177 if (find(ids.begin(), ids.end(), i) == ids.end())
183 void Tilesetlist::uninstantiateImages()
185 for (iterator it = begin(); it != end(); it++)
186 (*it)->uninstantiateImages();
188 void Tilesetlist::instantiateImages()
190 for (iterator it = begin(); it != end(); it++)
191 (*it)->instantiateImages();
194 Tileset *Tilesetlist::getTileset(std::string dir) const
196 TilesetMap::const_iterator it = d_tilesets.find(dir);
197 if (it == d_tilesets.end())
202 Tileset *Tilesetlist::getTileset(guint32 id) const
204 TilesetIdMap::const_iterator it = d_tilesetids.find(id);
205 if (it == d_tilesetids.end())
210 bool Tilesetlist::addToPersonalCollection(Tileset *tileset, std::string &new_subdir, guint32 &new_id)
212 //do we already have this one?
214 if (getTileset(tileset->getSubDir()) == getTileset(tileset->getId()) &&
215 getTileset(tileset->getSubDir()) != NULL)
217 tileset->setDirectory(getTileset(tileset->getId())->getDirectory());
221 //if the subdir conflicts with any other subdir, then change it.
222 if (getTileset(tileset->getSubDir()) != NULL)
225 for (int count = 0; count < 100; count++)
227 new_subdir = String::ucompose("%1%2", tileset->getSubDir(), count);
228 if (getTileset(new_subdir) == NULL)
236 tileset->setSubDir(new_subdir);
239 new_subdir = tileset->getSubDir();
241 //if the id conflicts with any other id, then change it
242 if (getTileset(tileset->getId()))
244 new_id = Tilesetlist::getNextAvailableId(tileset->getId());
245 tileset->setId(new_id);
248 new_id = tileset->getId();
250 //make the directory where the tileset is going to live.
251 std::string directory =
252 File::getUserTilesetDir() + tileset->getSubDir() + "/";
254 if (File::create_dir(directory) == false)
257 //okay now we copy the image files into the new directory
258 std::list<std::string> files;
259 tileset->getFilenames(files);
260 for (std::list<std::string>::iterator it = files.begin(); it != files.end();
262 File::copy(tileset->getFile(*it), directory + *it);
264 //save out the tileset file
265 tileset->setDirectory(directory);
266 XML_Helper helper(tileset->getConfigurationFile(), std::ios::out, false);
267 tileset->save(&helper);