00001 #include <iostream>
00002 #include <cctype>
00003
00004 #include "input.h"
00005 #include "arrutil.h"
00006 #include "menuresp.h"
00007
00008 #include "employee.h"
00009 #include "boss.h"
00010
00011 #define TEMPLATE_CLASSES_WONT_COMPILE
00012 #include "commission.h"
00013 #include "piece.h"
00014 #include "hourly.h"
00015 #include "array.h"
00016
00017 using namespace std;
00018
00019
00020
00021 template <typename Pointer>
00022 void free_one(Pointer & ptr) {
00023 delete ptr;
00024 ptr = NULL;
00025 return;
00026 }
00027
00028
00029
00030 void report_emp(const EmployeePtr & emp) {
00031 if (emp != NULL) {
00032 emp->print(cout);
00033 cout << " earned " << emp->earnings() << endl;
00034 }
00035 return;
00036 }
00037
00038
00039
00040 void update_size(long size, long & max, bool & done) {
00041 char yn;
00042 done = false;
00043 if (size == max) {
00044 yn = get_in_set("YyNn",
00045 "You have entered all the workers you can.\n"
00046 " Would you like to increase the size? ",
00047 "Yes or No, please...");
00048 if (toupper(yn) == 'Y') {
00049 max = get_bounded_lower(max+1, cin,
00050 "How many employees to handle now? ",
00051 false, "");
00052 }
00053 else {
00054 done = true;
00055 cout << "Then you aren't allowed to enter anyone!!" << endl;
00056 }
00057 }
00058 return;
00059 }
00060
00061 template <typename EmpPtrArray>
00062 void do_entry_menu(EmpPtrArray & arr, long & size, long & max) {
00063 const long MAX_NAME = 50;
00064
00065 double w, p;
00066 long q;
00067 char f[MAX_NAME], L[MAX_NAME];
00068 long choice;
00069 bool done;
00070
00071
00072
00073 MenuResponse entry_menu("+==============================+\n"
00074 "| 1) enter Boss worker |\n"
00075 "| 2) enter Commissioned worker |\n"
00076 "| 3) enter Piece worker |\n"
00077 "| 4) enter Hourly worker |\n"
00078 "| 5) Q\bReturn to Main Menu |\n"
00079 "+==============================+\n\n"
00080 "-\bEnter choice: ");
00081
00082 update_size(size, max, done);
00083 while (!done) {
00084 choice = entry_menu.get_response();
00085 if (choice == 4) {
00086 done = true;
00087 }
00088 else {
00089 cout << "Enter name for worker (first last): ";
00090 cin >> setw(MAX_NAME) >> f >> setw(MAX_NAME) >> L;
00091 switch (choice) {
00092 case 0: {
00093 cout << "Enter weekly wage: ";
00094 cin >> w;
00095 arr[size] = new Boss(f, L, w);
00096 } break;
00097 case 1: {
00098 cout << "Enter weekly wage, commission rate, and quantity sold: ";
00099 cin >> w >> p >> q;
00100 arr[size] = new CommissionWorker(f, L, w, p, q);
00101 } break;
00102 case 2: {
00103 cout << "Enter wage per piece and number of pieces: ";
00104 cin >> w >> q;
00105 arr[size] = new PieceWorker(f, L, w, q);
00106 } break;
00107 case 3: {
00108 cout << "Enter hourly wage and hours worked: ";
00109 cin >> w >> p;
00110 arr[size] = new HourlyWorker(f, L, w, p);
00111 } break;
00112 default: {
00113
00114 cout << "Invalid choice!" << endl;
00115 } break;
00116 }
00117 if (arr[size] != NULL) {
00118 size++;
00119 }
00120 update_size(size, max, done);
00121 }
00122 }
00123 return;
00124 }
00125
00126
00127
00128 enum CountType { Low, High, Both };
00129
00130 template <typename TypeBounded = double, typename BoundType = double>
00131 class Count_If_Bounded {
00132 BoundType low, hi;
00133 CountType which_bounds;
00134 mutable long count;
00135
00136 public:
00137 Count_If_Bounded(BoundType L = 0.0, BoundType H = 0.0, CountType w = Low)
00138 : low(L), hi(H), which_bounds(w), count(0) { }
00139 Count_If_Bounded(const Count_If_Bounded & cib)
00140 : low(cib.low), hi(cib.hi), which_bounds(cib.which_bounds),
00141 count(cib.count) { }
00142 ~Count_If_Bounded() {}
00143
00144 Count_If_Bounded & operator = (const Count_If_Bounded & cib) {
00145 low = cib.low;
00146 hi = cib.hi;
00147 which_bounds = cib.which_bounds;
00148 count = cib.count;
00149 return *this;
00150 }
00151
00152 bool operator () (TypeBounded well) const {
00153 bool ans = false;
00154 if (((which_bounds == Low) && (well >= low)) ||
00155 ((which_bounds == High) && (well <= hi)) ||
00156 ((which_bounds == Both) && ((well <= hi) && (well >= low)))) {
00157 ans = true;
00158 count++;
00159 }
00160 return ans;
00161 }
00162
00163 void set_count(long c = 0) { count = c; return; }
00164 void set_bounds(BoundType L, BoundType H, CountType w) {
00165 low = L;
00166 hi = H;
00167 which_bounds = w;
00168 count = 0;
00169 }
00170 long get_count(void) const { return count; }
00171 };
00172
00173 template <>
00174 class Count_If_Bounded<EmployeePtr> {
00175 double low, hi;
00176 CountType which_bounds;
00177 mutable long count;
00178 public:
00179 Count_If_Bounded(double L = 0.0, double H = 0.0, CountType w = Low)
00180 : low(L), hi(H), which_bounds(w), count(0) { }
00181 Count_If_Bounded(const Count_If_Bounded & cib)
00182 : low(cib.low), hi(cib.hi), which_bounds(cib.which_bounds),
00183 count(cib.count) { }
00184 ~Count_If_Bounded() {}
00185 Count_If_Bounded & operator = (const Count_If_Bounded & cib) {
00186 low = cib.low;
00187 hi = cib.hi;
00188 which_bounds = cib.which_bounds;
00189 count = cib.count;
00190 return *this;
00191 }
00192 bool operator () (EmployeePtr well) const {
00193 bool ans = false;
00194 if (well != NULL) {
00195 if (((which_bounds == Low) && (well->earnings() >= low)) ||
00196 ((which_bounds == High) && (well->earnings() <= hi)) ||
00197 ((which_bounds == Both) && ((well->earnings() <= hi) &&
00198 (well->earnings() >= low)))) {
00199 ans = true;
00200 count++;
00201 }
00202 }
00203 return ans;
00204 }
00205 void set_count(long c = 0) { count = c; return; }
00206 void set_bounds(double L, double H, CountType w) {
00207 low = L;
00208 hi = H;
00209 which_bounds = w;
00210 count = 0;
00211 }
00212 long get_count(void) const { return count; }
00213 };
00214
00215 typedef CountType PrintType;
00216
00217 template <typename TypeBounded = double, typename BoundType = double>
00218 class Print_If_Bounded {
00219 BoundType low, hi;
00220 PrintType which_bounds;
00221 ostream & print_on;
00222 long wide;
00223
00224 public:
00225 Print_If_Bounded(BoundType L = 0.0, BoundType H = 0.0, PrintType w = Low,
00226 long W = 5, ostream & o = cout)
00227 : low(L), hi(H), which_bounds(w), print_on(o), wide(W) { }
00228 Print_If_Bounded(const Print_If_Bounded & pib)
00229 : low(pib.low), hi(pib.hi), which_bounds(pib.which_bounds),
00230 print_on(pib.print_on), wide(pib.wide) { }
00231 ~Print_If_Bounded() {}
00232
00233 Print_If_Bounded & operator = (const Print_If_Bounded & pib) {
00234 low = pib.low;
00235 hi = pib.hi;
00236 which_bounds = pib.which_bounds;
00237 wide = pib.wide;
00238
00239 return *this;
00240 }
00241
00242 void operator () (TypeBounded well) const {
00243 if (((which_bounds == Low) && (well >= low)) ||
00244 ((which_bounds == High) && (well <= hi)) ||
00245 ((which_bounds == Both) && ((well <= hi) && (well >= low)))) {
00246 print_on << setw(wide) << well;
00247 }
00248 return;
00249 }
00250 };
00251
00252 template <>
00253 class Print_If_Bounded<EmployeePtr> {
00254 double low, hi;
00255 PrintType which_bounds;
00256 ostream & print_on;
00257 long wide;
00258
00259 public:
00260 Print_If_Bounded(double L = 0.0, double H = 0.0, PrintType w = Low,
00261 long W = 5, ostream & o = cout)
00262 : low(L), hi(H), which_bounds(w), print_on(o), wide(W) { }
00263 Print_If_Bounded(const Print_If_Bounded & pib)
00264 : low(pib.low), hi(pib.hi), which_bounds(pib.which_bounds),
00265 print_on(pib.print_on), wide(pib.wide) { }
00266 ~Print_If_Bounded() {}
00267 Print_If_Bounded & operator = (const Print_If_Bounded & pib) {
00268 low = pib.low;
00269 hi = pib.hi;
00270 which_bounds = pib.which_bounds;
00271 wide = pib.wide;
00272
00273 return *this;
00274 }
00275 void operator () (EmployeePtr well) const {
00276 if (well != NULL) {
00277 if (((which_bounds == Low) && (well->earnings() >= low)) ||
00278 ((which_bounds == High) && (well->earnings() <= hi)) ||
00279 ((which_bounds == Both) && ((well->earnings() <= hi) &&
00280 (well->earnings() >= low)))) {
00281 well->print(print_on);
00282 print_on << " earned " << well->earnings() << endl;
00283 }
00284 }
00285 return;
00286 }
00287 };
00288
00289
00290
00291 template <typename EmpPtrArray>
00292 void do_wage_count_menu(EmpPtrArray arr, long size) {
00293 MenuResponse wage_count_menu("################################\n"
00294 "# 1) count wages Above a limit #\n"
00295 "# 2) count wages Below a limit #\n"
00296 "# 3) count wages in a Range #\n"
00297 "################################\n\n"
00298 "-\bEnter choice: ");
00299 long choice;
00300 double limit1, limit2;
00301 Count_If_Bounded<EmployeePtr> count_em;
00302
00303 choice = wage_count_menu.get_response();
00304 switch (choice) {
00305 case 0: {
00306 limit1 = get_bounded_lower(-1.0, cin,
00307 "Enter (inclusive) limit for counting: ");
00308 count_em.set_bounds(limit1, limit2, Low);
00309 for_each(arr, 0, size-1, count_em);
00310 cout << "Found " << count_em.get_count() << " personnell with "
00311 << "salaries above " << limit1 << "." << endl;
00312 } break;
00313 case 1: {
00314 limit2 = get_bounded_lower(-1.0, cin,
00315 "Enter (inclusive) limit for counting: ");
00316 count_em.set_bounds(limit1, limit2, High);
00317 for_each(arr, 0, size-1, count_em);
00318 cout << "Found " << count_em.get_count() << " personnell with "
00319 << "salaries below " << limit2 << "." << endl;
00320 } break;
00321 case 2: {
00322 limit1 = get_bounded_lower(-1.0, cin,
00323 "Enter (inclusive) lower limit"
00324 " for counting: ");
00325 limit2 = get_bounded_lower(limit1, cin,
00326 "Enter (inclusive) upper limit"
00327 " for counting: ");
00328 count_em.set_bounds(limit1, limit2, Both);
00329 for_each(arr, 0, size-1, count_em);
00330 cout << "Found " << count_em.get_count() << " personnell with "
00331 << "salaries between " << limit1 << " and " << limit2
00332 << "." << endl;
00333 } break;
00334 default: {
00335 cout << "Invalid choice!" << endl;
00336 } break;
00337 }
00338 return;
00339 }
00340
00341 template <typename EmpPtrArray>
00342 void do_wage_print_menu(EmpPtrArray arr, long size) {
00343 MenuResponse wage_print_menu("################################\n"
00344 "# 1) print wages Above a limit #\n"
00345 "# 2) print wages Below a limit #\n"
00346 "# 3) print wages in a Range #\n"
00347 "################################\n\n"
00348 "-\bEnter choice: ");
00349 long choice;
00350 double limit1, limit2;
00351
00352 choice = wage_print_menu.get_response();
00353 switch (choice) {
00354 case 0: {
00355 limit1 = get_bounded_lower(-1.0, cin,
00356 "Enter (inclusive) limit for printing: ");
00357 for_each(arr, 0, size-1,
00358 Print_If_Bounded<EmployeePtr>(limit1, limit2, Low));
00359 } break;
00360 case 1: {
00361 limit2 = get_bounded_lower(-1.0, cin,
00362 "Enter (inclusive) limit for printing: ");
00363 for_each(arr, 0, size-1,
00364 Print_If_Bounded<EmployeePtr>(limit1, limit2, High));
00365 } break;
00366 case 2: {
00367 limit1 = get_bounded_lower(-1.0, cin,
00368 "Enter (inclusive) lower limit"
00369 " for printing: ");
00370 limit2 = get_bounded_lower(limit1, cin,
00371 "Enter (inclusive) upper limit"
00372 " for printing: ");
00373 for_each(arr, 0, size-1,
00374 Print_If_Bounded<EmployeePtr>(limit1, limit2, Both));
00375 } break;
00376 default: {
00377 cout << "Invalid choice!" << endl;
00378 } break;
00379 }
00380 return;
00381 }
00382
00383 template <typename EmpPtrArray>
00384 void do_wage_menu(EmpPtrArray arr, long size) {
00385 MenuResponse wage_menu("############################\n"
00386 "# 1) Print certain wages #\n"
00387 "# 2) Count certain wages #\n"
00388 "# 3) Q\bReturn to Main Menu #\n"
00389 "############################\n\n"
00390 "-\bEnter choice: ");
00391 long choice;
00392 bool done = false;
00393 choice = wage_menu.get_response();
00394 done = (choice == 2);
00395 while (!done) {
00396 switch(choice) {
00397 case 0: {
00398 do_wage_print_menu(arr, size);
00399 } break;
00400 case 1: {
00401 do_wage_count_menu(arr, size);
00402 } break;
00403 default: {
00404 cout << "Invalid choice!" << endl;
00405 } break;
00406 }
00407 choice = wage_menu.get_response();
00408 done = (choice == 2);
00409 }
00410 return;
00411 }
00412
00413
00414
00415 template <typename EmpPtrArray>
00416 void do_main_menu(EmpPtrArray & arr, long & size, long & max) {
00417 MenuResponse main_menu("1) Enter new workers\n"
00418 "2) Print workers out\n"
00419 "3) Wage statistics\n"
00420 "4) M\bR\bQuit program\n\n"
00421 "-\bEnter choice: ");
00422 long choice;
00423 bool done = false;
00424 choice = main_menu.get_response();
00425 done = (choice == 3);
00426 while (!done) {
00427 switch(choice) {
00428 case 0: {
00429 do_entry_menu(arr, size, max);
00430 } break;
00431 case 1: {
00432 for_each(arr, 0, size-1, report_emp);
00433 } break;
00434 case 2: {
00435 do_wage_menu(arr, size);
00436 } break;
00437 default: {
00438 cout << "Invalid choice!" << endl;
00439 } break;
00440 }
00441 choice = main_menu.get_response();
00442 done = (choice == 3);
00443 }
00444 return;
00445 }
00446
00447
00448
00449 int main(void) {
00450 Array<EmployeePtr> arr;
00451 long cur_emp, max_emp;
00452
00453 max_emp = get_bounded_lower(0, cin,
00454 "How many employees to start? ",
00455 false, "");
00456 arr.resize(max_emp);
00457 for (cur_emp = 0; cur_emp < max_emp; cur_emp++) {
00458 arr[cur_emp] = NULL;
00459 }
00460 cur_emp = 0;
00461 do_main_menu(arr, cur_emp, max_emp);
00462 for_each(arr, 0, cur_emp-1, free_one<EmployeePtr>);
00463
00464 cout << endl
00465 << "Thanks for using our employee program!" << endl
00466 << endl
00467 << "Come again soon!" << endl
00468 << endl;
00469
00470 return 0;
00471 }