1 // Copyright (C) 2008 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 <sigc++/functors/mem_fun.h>
24 #include "citysetlist.h"
25 #include "ucompose.hpp"
31 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
34 Citysetlist* Citysetlist::s_instance = 0;
36 Citysetlist* Citysetlist::getInstance()
39 s_instance = new Citysetlist();
44 void Citysetlist::deleteInstance()
52 void Citysetlist::loadCitysets(std::list<std::string> citysets)
54 for (std::list<std::string>::const_iterator i = citysets.begin();
55 i != citysets.end(); i++)
57 Cityset *cityset = loadCityset(*i);
65 Citysetlist::Citysetlist()
68 std::list<std::string> citysets = Cityset::scanSystemCollection();
69 loadCitysets(citysets);
70 citysets = Cityset::scanUserCollection();
71 loadCitysets(citysets);
75 Citysetlist::~Citysetlist()
77 for (iterator it = begin(); it != end(); it++)
81 std::list<std::string> Citysetlist::getNames()
83 std::list<std::string> names;
84 for (iterator it = begin(); it != end(); it++)
85 names.push_back((*it)->getName());
89 std::list<std::string> Citysetlist::getNames(guint32 tilesize)
91 std::list<std::string> names;
92 for (iterator it = begin(); it != end(); it++)
93 if ((*it)->getTileSize() == tilesize)
94 names.push_back((*it)->getName());
98 Cityset *Citysetlist::loadCityset(std::string name)
100 debug("Loading cityset " <<File::get_basename(File::get_dirname(name)));
102 Cityset *cityset = Cityset::create(name);
106 if (cityset->validate() == false)
108 cerr << "Error! cityset: `" << cityset->getName() <<
109 "' is invalid. Skipping." << endl;
114 if (d_citysetids.find(cityset->getId()) != d_citysetids.end())
116 Cityset *c = (*d_citysetids.find(cityset->getId())).second;
117 cerr << "Error! cityset: `" << cityset->getName() <<
118 "' shares a duplicate cityset id with `" << c->getConfigurationFile()
119 << "'. Skipping." << endl;
124 if (d_citysetids.find(cityset->getId()) != d_citysetids.end())
126 Cityset *c = (*d_citysetids.find(cityset->getId())).second;
127 cerr << "Error! cityset: `" << cityset->getName() <<
128 "' has a duplicate cityset id with `" << c->getConfigurationFile() <<
129 "'. Skipping." << endl;
136 void Citysetlist::add(Cityset *cityset)
138 std::string subdir = File::get_basename(cityset->getDirectory());
140 cityset->setSubDir(subdir);
141 d_dirs[String::ucompose("%1 %2", cityset->getName(), cityset->getTileSize())] = subdir;
142 d_citysets[subdir] = cityset;
143 d_citysetids[cityset->getId()] = cityset;
146 void Citysetlist::getSizes(std::list<guint32> &sizes)
148 for (iterator i = begin(); i != end(); i++)
150 if (find (sizes.begin(), sizes.end(), (*i)->getTileSize()) == sizes.end())
151 sizes.push_back((*i)->getTileSize());
155 std::string Citysetlist::getCitysetDir(std::string name, guint32 tilesize)
157 return d_dirs[String::ucompose("%1 %2", name, tilesize)];
159 void Citysetlist::instantiateImages()
161 for (iterator it = begin(); it != end(); it++)
162 (*it)->instantiateImages();
164 void Citysetlist::uninstantiateImages()
166 for (iterator it = begin(); it != end(); it++)
167 (*it)->uninstantiateImages();
170 Cityset *Citysetlist::getCityset(guint32 id)
172 if (d_citysetids.find(id) == d_citysetids.end())
174 return d_citysetids[id];
177 Cityset *Citysetlist::getCityset(std::string dir)
179 if (d_citysets.find(dir) == d_citysets.end())
181 return d_citysets[dir];
183 bool Citysetlist::addToPersonalCollection(Cityset *cityset, std::string &new_subdir, guint32 &new_id)
185 //do we already have this one?
186 if (getCityset(cityset->getSubDir()) == getCityset(cityset->getId()) &&
187 getCityset(cityset->getSubDir()) != NULL)
189 cityset->setDirectory(getCityset(cityset->getId())->getDirectory());
193 //if the subdir conflicts with any other subdir, then change it.
194 if (getCityset(cityset->getSubDir()) != NULL)
197 for (int count = 0; count < 100; count++)
199 new_subdir = String::ucompose("%1%2", cityset->getSubDir(), count);
200 if (getCityset(new_subdir) == NULL)
208 cityset->setSubDir(new_subdir);
211 new_subdir = cityset->getSubDir();
213 //if the id conflicts with any other id, then change it
214 if (getCityset(cityset->getId()) != NULL)
216 new_id = Citysetlist::getNextAvailableId(cityset->getId());
217 cityset->setId(new_id);
220 new_id = cityset->getId();
222 //make the directory where the cityset is going to live.
223 std::string directory =
224 File::getUserCitysetDir() + cityset->getSubDir() + "/";
226 if (File::create_dir(directory) == false)
229 //okay now we copy the image files into the new directory
230 std::list<std::string> files;
231 cityset->getFilenames(files);
232 for (std::list<std::string>::iterator it = files.begin(); it != files.end();
234 File::copy(cityset->getFile(*it), directory + *it);
236 //save out the cityset file
237 cityset->setDirectory(directory);
238 XML_Helper helper(cityset->getConfigurationFile(), std::ios::out, false);
239 cityset->save(&helper);
244 int Citysetlist::getNextAvailableId(int after)
246 std::list<guint32> ids;
247 std::list<std::string> citysets = Cityset::scanSystemCollection();
248 //there might be IDs in invalid armysets.
249 for (std::list<std::string>::const_iterator i = citysets.begin();
250 i != citysets.end(); i++)
252 Cityset *cityset = Cityset::create(*i);
255 ids.push_back(cityset->getId());
259 citysets = Cityset::scanUserCollection();
260 for (std::list<std::string>::const_iterator i = citysets.begin();
261 i != citysets.end(); i++)
263 Cityset *cityset = Cityset::create(*i);
266 ids.push_back(cityset->getId());
270 for (guint32 i = after + 1; i < 1000000; i++)
272 if (find(ids.begin(), ids.end(), i) == ids.end())