]> git.tdb.fi Git - r2c2.git/blob - source/shoppinglist/main.cpp
Allow negative counts for writing off tracks
[r2c2.git] / source / shoppinglist / main.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <map>
9 #include <msp/core/getopt.h>
10 #include <msp/datafile/loader.h>
11 #include <msp/datafile/parser.h>
12 #include <msp/io/print.h>
13
14 using namespace std;
15 using namespace Msp;
16
17 class ShoppingList
18 {
19 public:
20         ShoppingList(int, char **);
21         void print(IO::Base &);
22 private:
23         class InventoryLoader: public DataFile::Loader
24         {
25         public:
26                 InventoryLoader(ShoppingList &);
27         private:
28                 ShoppingList &sl;
29
30                 void track(unsigned, int);
31         };
32
33         class LayoutLoader: public DataFile::Loader
34         {
35         public:
36                 LayoutLoader(ShoppingList &);
37         private:
38                 ShoppingList &sl;
39
40                 void track(unsigned);
41         };
42
43         map<unsigned, unsigned> inventory;
44         map<unsigned, unsigned> layout;
45
46         void load_inventory(const string &);
47         void load_layout(const string &);
48 };
49
50 int main(int argc, char **argv)
51 {
52         ShoppingList sl(argc, argv);
53         sl.print(IO::cout);
54         return 0;
55 }
56
57 ShoppingList::ShoppingList(int argc, char **argv)
58 {
59         string inv_fn="inventory";
60         GetOpt getopt;
61         getopt.add_option('i', "inventory", inv_fn, GetOpt::REQUIRED_ARG);
62         getopt(argc,argv);
63
64         load_inventory(inv_fn);
65         load_layout(getopt.get_args().front());
66 }
67
68 void ShoppingList::load_inventory(const string &fn)
69 {
70         IO::File in(fn);
71         DataFile::Parser parser(in, fn);
72         InventoryLoader il(*this);
73         il.load(parser);
74 }
75
76 void ShoppingList::load_layout(const string &fn)
77 {
78         IO::File in(fn);
79         DataFile::Parser parser(in, fn);
80         LayoutLoader ll(*this);
81         ll.load(parser);
82 }
83
84 void ShoppingList::print(IO::Base &out)
85 {
86         IO::print(out, "// Need to get:\n");
87         for(map<unsigned, unsigned>::iterator i=layout.begin(); i!=layout.end(); ++i)
88         {
89                 map<unsigned, unsigned>::iterator j=inventory.find(i->first);
90                 if(j!=inventory.end())
91                 {
92                         if(j->second<i->second)
93                                 IO::print(out, "track %d %d;\n", i->first, i->second-j->second);
94                 }
95                 else
96                         IO::print(out, "track %d %d;\n", i->first, i->second);
97         }
98
99         IO::print(out, "// Pre-existing:\n");
100         for(map<unsigned, unsigned>::iterator i=layout.begin(); i!=layout.end(); ++i)
101         {
102                 map<unsigned, unsigned>::iterator j=inventory.find(i->first);
103                 if(j!=inventory.end())
104                         IO::print(out, "track %d %d;\n", i->first, min(i->second, j->second));
105         }
106
107         IO::print(out, "// Unused:\n");
108         for(map<unsigned, unsigned>::iterator i=inventory.begin(); i!=inventory.end(); ++i)
109         {
110                 map<unsigned, unsigned>::iterator j=layout.find(i->first);
111                 if(j!=layout.end())
112                 {
113                         if(j->second<i->second)
114                                 IO::print(out, "track %d %d;\n", i->first, i->second-j->second);
115                 }
116                 else
117                         IO::print(out, "track %d %d;\n", i->first, i->second);
118         }
119 }
120
121 ShoppingList::InventoryLoader::InventoryLoader(ShoppingList &s):
122         sl(s)
123 {
124         add("track", &InventoryLoader::track);
125 }
126
127 void ShoppingList::InventoryLoader::track(unsigned part, int count)
128 {
129         sl.inventory[part]+=count;
130 }
131
132 ShoppingList::LayoutLoader::LayoutLoader(ShoppingList &s):
133         sl(s)
134 {
135         add("track", &LayoutLoader::track);
136         add("base");
137         add("route");
138 }
139
140 void ShoppingList::LayoutLoader::track(unsigned part)
141 {
142         ++sl.layout[part];
143 }