0a1
> #include <vector>
1a3
> #include <strstream>
3d4
< #include <cstdlib> /* exit() */
5a7
> #include <cassert>
8a11,12
> #include "DataNotFoundException.h"
> 
13a18
> 
16,17c21
< 
<     void revert(int period)
---
>     void transfer()
19,23d22
<         ZONE *zone;
<         AU *au;
<         TIMBER_CLASS *timber_class;
< 
<         /* timber_class type reversions */
25,55d23
<         pApp->m_zoneList = (LIST_PTR *)List::reset(pApp->m_zoneList);
<         zone = (ZONE *)List::next(pApp->m_zoneList);
<         while (zone!= 0)
<         {
<             zone->aulist = (LIST_PTR *)List::reset(zone->aulist);
<             au = static_cast<AU*>(List::next(zone->aulist));
<             while (au!= 0)
<             {
<                 au->classlist = (LIST_PTR *)List::reset(au->classlist);
<                 timber_class = (TIMBER_CLASS *)List::next(au->classlist);
<                 while (timber_class!= 0)
<                 {
<                     timber_class->MerchArea = 0.0f;
< #ifdef _TSB_MERCHAREA_DEBUG
<                     cout << "MerchArea set to zero: " << timber_class->MerchArea << endl;
< #endif
<                     timber_class->transferred = false;
<                     if ((timber_class->class_type==FssimApp::DEFERRED)||(timber_class->class_type==FssimApp::NONCONTRIBUTING))
<                     {
<                         if (timber_class->age+pApp->m_periodLength[period]>=timber_class->reversion_age)
<                         {
<                             timber_class->class_type=FssimApp::OPERABLE;
<                         }
<                     }
<                     timber_class = (TIMBER_CLASS *)List::next(au->classlist);
<                 }
<                 au = static_cast<AU*>(List::next(zone->aulist));
<             }
<             zone = (ZONE *)List::next(pApp->m_zoneList);
<         }
<     }
57,70c25
<     void transfer(int period)
<     {
<         ZONE* zone;
<         //ZONE* to_zone; // unreferenced!
<         AU* au;
<         // AU* to_au; //unreferenced!
<         TIMBER_CLASS		*timber_class, *newclass;
<         GROUP		*group;
<         TRANSFER	*active_transfer, *transfer;
<         int		clone_class, TransferPerformed;
<         LIST_REC	*listSaveZoneList, *listSaveAuList, *listSaveClassList;
<         int		ToAge,ToType,ToRAge;
<         int		FromAge,FromType,FromRAge;
<         char		FromZone[20], FromAU[20], ToZone[20], ToAU[20];
---
>         cout << "Period : " << pApp->m_currentPeriod << " - Transfer/Reversions" << endl;
72,74d26
<         printf("\nPeriod : %3d - Transfer/Reversions", period);
< 
<         FssimApp* pApp = FssimApp::getApp();
77,81c29,35
<         /* transfers */
<         TransferPerformed = false;
<         pApp->m_zoneList = (LIST_PTR *)List::reset(pApp->m_zoneList);
<         zone = (ZONE *)List::next(pApp->m_zoneList);
<         while (zone != 0)
---
>         bool TransferPerformed = false;
> 
>         // save a copy of the main zone list
>         vector<ZoneStruct*> listSaveZoneList = pApp->m_zoneList;
> 
>         typedef vector<ZoneStruct*>::iterator ZI;
>         for (ZI zoneIter = listSaveZoneList.begin(); zoneIter != listSaveZoneList.end(); ++zoneIter)
83c37,43
<             if (pApp->m_zoneList!= 0)
---
>             vector<AUStruct*>& auList = (*zoneIter)->aulist;
> 
>             // save a copy of the au list for each zone
>             vector<AUStruct*> listSaveAuList = auList;
> 
>             typedef vector<AUStruct*>::iterator AI;
>             for (AI auIter = listSaveAuList.begin(); auIter != listSaveAuList.end(); ++auIter)
85,93c45,51
<                 listSaveZoneList = (LIST_REC *)pApp->m_zoneList->current;
<             } else {
<                 listSaveZoneList = 0;
<             }
<             zone->aulist = (LIST_PTR *)List::reset(zone->aulist);
<             au = static_cast<AU*>(List::next(zone->aulist));
<             while (au!= 0)
<             {
<                 if (zone->aulist!= 0)
---
>                 multimap<int, TimberClassStruct*>& timberClassList = (*auIter)->classlist;
> 
>                 // save a copy of the class list for each au of each zone
>                 multimap<int, TimberClassStruct*> listSaveClassList = timberClassList;
> 
>                 typedef multimap<int, TimberClassStruct*>::iterator CI;
>                 for (CI classIter = listSaveClassList.begin(); classIter != listSaveClassList.end(); ++classIter)
95,103c53,63
<                     listSaveAuList = (LIST_REC *)zone->aulist->current;
<                 } else {
<                     listSaveAuList = 0;
<                 }
<                 au->classlist = (LIST_PTR *)List::reset(au->classlist);
<                 timber_class = (TIMBER_CLASS *)List::next(au->classlist);
<                 while (timber_class!= 0)
<                 {
<                     if (au->classlist!= 0)
---
>                     TimberClassStruct* pCurrentTimberClass = classIter->second;
> 
> #ifdef _TSB_TRANSFER_DEBUG
>                     cout << endl << "transfer: age: " << pCurrentTimberClass->age << endl;
> #endif
>                     // save a copy of the class list for each au of each zone
>                     multimap<int, TimberClassStruct*> listSaveClassList = timberClassList;
> 
>                     assert(pCurrentTimberClass->parent_au != 0);
> 
>                     if ((pCurrentTimberClass->class_type!=GroupDefStruct::INACTIVE)&&(pCurrentTimberClass->transferred==false))
105,153c65,67
<                         listSaveClassList = (LIST_REC *)au->classlist->current;
<                     } else {
<                         listSaveClassList = 0;
<                     }
<                     if ((timber_class->class_type!=FssimApp::INACTIVE) && (timber_class->transferred == false))
<                     {
<                         active_transfer = 0;
<                         timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<                         group = (GROUP *)List::next(timber_class->float_group_list);
<                         while (group != 0)
<                         {
<                             group->transferlist = (LIST_PTR *)List::reset(group->transferlist);
<                             transfer = (TRANSFER *)List::next(group->transferlist);
<                             while (transfer != 0)
<                             {
<                                 if ((period>=transfer->start_period)&&(period<=transfer->end_period))
<                                 {
<                                     if (active_transfer!= 0)
<                                     {
<                                         printf("\n\nERROR: Multiple transfer records for elements of group(%s)\n\n", group->label);
<                                         exit(1);
<                                     }
<                                     active_transfer = transfer;
<                                 }
<                                 transfer = (TRANSFER *)List::next(group->transferlist);
<                             }
<                             group = (GROUP *)List::next(timber_class->float_group_list);
<                         }
<                         timber_class->static_group_list = (LIST_PTR *)List::reset(timber_class->static_group_list);
<                         group = (GROUP *)List::next(timber_class->static_group_list);
<                         while (group != 0)
<                         {
<                             group->transferlist = (LIST_PTR *)List::reset(group->transferlist);
<                             transfer = (TRANSFER *)List::next(group->transferlist);
<                             while (transfer != 0)
<                             {
<                                 if ((period>=transfer->start_period)&&(period<=transfer->end_period))
<                                 {
<                                     if (active_transfer!= 0)
<                                     {
<                                         printf("\n\nERROR: Multiple transfer records for elements of group(%s)\n\n", group->label);
<                                         exit(1);
<                                     }
<                                     active_transfer = transfer;
<                                 }
<                                 transfer = (TRANSFER *)List::next(group->transferlist);
<                             }
<                             group = (GROUP *)List::next(timber_class->static_group_list);
<                         }
---
>                         TransferStruct* active_transfer = 0;
>                         active_transfer = do_active_transfer(pCurrentTimberClass->float_group_list, active_transfer);
>                         active_transfer = do_active_transfer(pCurrentTimberClass->static_group_list, active_transfer);
155c69
<                         if (active_transfer!= 0)
---
>                         if (active_transfer != 0)
157,158c71,72
< 
<                             clone_class = false;
---
>                             char FromZone[FssimUtil::MAX_LABEL_LENGTH];
>                             bool clone_class = false;
160,161c74,75
<                             sprintf(FromZone, "%s", timber_class->parent_zone->label);
<                             if (strcmp(active_transfer->to_zone,FssimApp::m_kNullString)!=0)
---
>                             strcpy(FromZone, pCurrentTimberClass->parent_zone->label);
>                             if (active_transfer->m_zoneID != FssimUtil::DUMMY_INPUT)
164,166c78,80
<                                 timber_class->parent_zone->area -= timber_class->area;
<                                 timber_class->parent_zone = (ZONE *)func_find_zone(active_transfer->to_zone);
<                                 if (timber_class->parent_zone == 0)
---
>                                 pCurrentTimberClass->parent_zone->area -= pCurrentTimberClass->area;
>                                 pCurrentTimberClass->parent_zone = ZoneStruct::find(active_transfer->m_zoneID);
>                                 if (pCurrentTimberClass->parent_zone == 0)
168,169c82,83
<                                     printf("\n\nERROR: transfer(): Could not find specified zone(%s)\n\n", active_transfer->to_zone);
<                                     exit(1);
---
>                                     throw DataNotFoundException(FssimUtil::m_kZoneIdentifier,
> 				                                                active_transfer->m_zoneID);
171c85
<                                 timber_class->parent_zone->area += timber_class->area;
---
>                                 pCurrentTimberClass->parent_zone->area += pCurrentTimberClass->area;
173,176c87,88
<                             else
<                             {
<                                 timber_class->parent_zone = timber_class->parent_zone;
<                             }
---
> 
>                             char ToZone[FssimUtil::MAX_LABEL_LENGTH];
178c90
<                             sprintf(ToZone, "%s", timber_class->parent_zone->label);
---
>                             strcpy(ToZone, pCurrentTimberClass->parent_zone->label);
179a92
>                             char FromAU[FssimUtil::MAX_LABEL_LENGTH];
181,182c94,95
<                             sprintf(FromAU, "%s", timber_class->parent_au->label);
<                             if (strcmp(active_transfer->to_au,FssimApp::m_kNullString)!=0)
---
>                             strcpy(FromAU, pCurrentTimberClass->parent_au->label);
>                             if (active_transfer->m_auLabelIndex != FssimUtil::DUMMY_INPUT)
185,190c98,99
<                                 timber_class->parent_au = static_cast<AU*>(func_find_au(timber_class->parent_zone, active_transfer->to_au));
< #ifdef _TSB_VERBOSE
<                                 cout << endl << "transferring to parent_au id: " << timber_class->parent_au->id << endl;
< #endif
< #ifdef _TSB_VERBOSE
<                                 if (timber_class->parent_zone->id == 3 && timber_class->parent_au->id > 14)
---
>                                 pCurrentTimberClass->parent_au = pCurrentTimberClass->parent_zone->findAU(active_transfer->m_auLabelIndex);
>                                 if (0 == pCurrentTimberClass->parent_au)
192,194c101,105
<                                     cout << endl << "class zone/parent_au/block/type: "
<                                      << timber_class->parent_zone->id << "/" << timber_class->parent_au->id << "/"
<                                      << timber_class->parent_block->label << "/" << timber_class->class_type;
---
>                                     ostringstream invalidType;
>                                     invalidType << FssimUtil::m_kZoneIdentifier << "/" << FssimUtil::m_kAUIdentifier;
>                                     throw DataNotFoundException(invalidType.str(),
>                                                                 pCurrentTimberClass->parent_zone->id,
>                                                                 active_transfer->m_auLabelIndex);
196,201d106
< #endif
<                                 if (timber_class->parent_au == 0)
<                                 {
<                                     printf("\n\nERROR: transfer(): Could not find specified zone/AU (%s,%s)\n\n", timber_class->parent_zone->label, active_transfer->to_au);
<                                     exit(1);
<                                 }
203,209c108,111
<                             // what was steve thinking??? (self-assignment is futile!)
<                             /*
<                             else
<                             {
<                                 timber_class->parent_au = timber_class->parent_au;
<                             }
<                             */
---
> 
>                             assert(0 != pCurrentTimberClass->parent_au);
> 
>                             char ToAU[FssimUtil::MAX_LABEL_LENGTH];
211c113
<                             sprintf(ToAU, "%s", timber_class->parent_au->label);
---
>                             strcpy(ToAU, pCurrentTimberClass->parent_au->label);
213,214c115,116
<                             FromAge = timber_class->age;
<                             if (active_transfer->to_age != FssimApp::DUMMYINPUT)
---
>                             int FromAge = pCurrentTimberClass->age;
>                             if (active_transfer->to_age != FssimUtil::DUMMY_INPUT)
216c118
<                                 timber_class->age = active_transfer->to_age;
---
>                                 pCurrentTimberClass->age = active_transfer->to_age;
218,225c120,122
<                             /*
<                             else
<                             {
<                                 timber_class->age = timber_class->age;
<                             }
<                             */
< #ifdef _TSB_REGEN_DEBUG
<                             cout << endl << "transferred to age: " << timber_class->age << endl;
---
> 
> #ifdef _TSB_TRANSFER_DEBUG
>                             cout << endl << "transferred to age: " << pCurrentTimberClass->age << endl;
227c124
<                             ToAge = timber_class->age;
---
>                             int ToAge = pCurrentTimberClass->age;
229,230c126,127
<                             FromType = timber_class->class_type;
<                             if (active_transfer->to_ctype != FssimApp::DUMMYINPUT)
---
>                             GroupDefStruct::TimberClassType FromType = pCurrentTimberClass->class_type;
>                             if (active_transfer->to_ctype != FssimUtil::DUMMY_INPUT)
232,235c129
<                                 timber_class->class_type = active_transfer->to_ctype;
< #ifdef _TSB_VERBOSE
<                                 cout << "transferring to class_type: " << timber_class->class_type << endl;
< #endif
---
>                                 pCurrentTimberClass->class_type = active_transfer->to_ctype;
237,243d130
<                             /*
<                             else
<                             {
<                                 timber_class->class_type = timber_class->class_type;
<                             }
<                             */
<                             ToType = timber_class->class_type;
245,246c132,135
<                             FromRAge = timber_class->reversion_age;
<                             if (active_transfer->to_rage != FssimApp::DUMMYINPUT)
---
>                             GroupDefStruct::TimberClassType ToType = pCurrentTimberClass->class_type;
> 
>                             int FromRAge = pCurrentTimberClass->reversion_age;
>                             if (active_transfer->to_rage != FssimUtil::DUMMY_INPUT)
248c137
<                                 timber_class->reversion_age = active_transfer->to_rage;
---
>                                 pCurrentTimberClass->reversion_age = active_transfer->to_rage;
250,256d138
<                             /*
<                             else
<                             {
<                                 timber_class->reversion_age = timber_class->reversion_age;
<                             }
<                             */
<                             ToRAge = timber_class->reversion_age;
258,260c140,145
<                             timber_class->float_group_list = (LIST_PTR *)List::reset(timber_class->float_group_list);
<                             group = (GROUP *)List::next(timber_class->float_group_list);
<                             while (group != 0)
---
>                             int ToRAge = pCurrentTimberClass->reversion_age;
> 
>                             list<GroupStruct*>& floatGroupList = pCurrentTimberClass->float_group_list;
>                             typedef list<GroupStruct*>::iterator GI;
>                             for (GI groupIter = floatGroupList.begin();
>                                     groupIter != floatGroupList.end(); ++groupIter)
262,263c147,148
<                                 group->area -= timber_class->area;
<                                 group = (GROUP *)List::next(timber_class->float_group_list);
---
>                                 (*groupIter)->area -= pCurrentTimberClass->area;
> 
265,266c150
<                             List::done(timber_class->float_group_list);
<                             timber_class->float_group_list = 0;
---
>                             floatGroupList.clear();
268d151
< 
271c154
<                                 period,
---
>                                 pApp->m_currentPeriod,
275c158
<                                 timber_class->area,
---
>                                 pCurrentTimberClass->area,
281c164
<                                 timber_class->area,
---
>                                 pCurrentTimberClass->area,
285c168,169
<                             if (clone_class==true)
---
>                             TimberClassStruct* newclass = 0;
> 			                if (clone_class == true)
287,295c171,179
<                                 newclass = (TIMBER_CLASS *)init_make_class(timber_class->parent_zone,
<                                     timber_class->parent_au,
<                                     timber_class->parent_block,
<                                     timber_class->age,
<                                     timber_class->width,
<                                     timber_class->area,
<                                     timber_class->class_type,
<                                     timber_class->reversion_age,
<                                     timber_class->ReEntryLag,
---
>                                 newclass = (TimberClassStruct *)init_make_class(pCurrentTimberClass->parent_zone,
>                                     pCurrentTimberClass->parent_au,
>                                     pCurrentTimberClass->parent_block,
>                                     pCurrentTimberClass->age,
>                                     pCurrentTimberClass->width,
>                                     pCurrentTimberClass->area,
>                                     pCurrentTimberClass->class_type,
>                                     pCurrentTimberClass->reversion_age,
>                                     pCurrentTimberClass->ReEntryLag,
297,298c181,182
<                                     timber_class->static_group_list,
<                                     timber_class->roaded,
---
>                                     &(pCurrentTimberClass->static_group_list),
>                                     pCurrentTimberClass->roaded,
301,305c185,186
<                                 timber_class->class_type = FssimApp::INACTIVE;
< #ifdef _TSB_VERBOSE
<                                 cout << "transferring to inactive: " << timber_class->class_type << endl;
< #endif
< #ifdef _TSB_CLONE_DEBUG
---
>                                 pCurrentTimberClass->class_type = GroupDefStruct::INACTIVE;
> #ifdef _TSB_TRANSFER_DEBUG
307c188
<                                         timber_class->parent_au->id, timber_class->parent_zone->id);
---
>                                         pCurrentTimberClass->parent_au->id, pCurrentTimberClass->parent_zone->id);
314c195
<                                 newclass = timber_class;
---
>                                 newclass = pCurrentTimberClass;
318,320c199,202
<                             newclass->parent_au->EligibleGroupList = (LIST_PTR *)List::reset(newclass->parent_au->EligibleGroupList);
<                             group = (GROUP *)List::next(newclass->parent_au->EligibleGroupList);
<                             while (group != 0)
---
> 
>                             typedef list<int>::iterator GII;
> 			                for (GII groupIndexIter = newclass->parent_au->m_eligibleGroupList.begin();
>                                     groupIndexIter != newclass->parent_au->m_eligibleGroupList.end(); ++groupIndexIter)
322c204,205
<                                 if (group->grouptype==FssimApp::FLOAT_GROUP)
---
>                                 GroupStruct* pGroup = GroupStruct::find(*groupIndexIter);
>                                 if (pGroup->grouptype == GroupDefStruct::FLOAT_GROUP)
324c207,209
<                                     if (func_group_membership(group, period, FssimApp::BEFORE, newclass->parent_zone->label, newclass->parent_au->label, newclass->parent_block->label, newclass->age, newclass->width, newclass->class_type)==true)
---
>                                     if ( pGroup->isMember(newclass->age, newclass->width, newclass->parent_block->id,
>                                                           newclass->parent_zone->id, newclass->class_type,
>                                                           newclass->parent_au->m_labelIndex) )
326,327c211,213
<                                         newclass->float_group_list = (LIST_PTR *)List::insert(newclass->float_group_list, group, group->id);
<                                         group->area += newclass->area;
---
>                                         // insert into float group list
>                                         newclass->float_group_list.push_back(pGroup);
>                                         pGroup->area += newclass->area;
330c216
<                                 group = (GROUP *)List::next(newclass->parent_au->EligibleGroupList);
---
> 
334,339d219
< 
<                     if (listSaveClassList != 0)
<                     {
<                         au->classlist->current = (LIST_REC *)listSaveClassList;
<                     }
<                     timber_class = (TIMBER_CLASS *)List::next(au->classlist);
341c221
<                 if (listSaveAuList!= 0)
---
>                 if ( !listSaveClassList.empty() )
343c223
<                     zone->aulist->current = (LIST_REC *)listSaveAuList;
---
>                     timberClassList = listSaveClassList;
345d224
<                 au = static_cast<AU*>(List::next(zone->aulist));
347c226
<             if (listSaveZoneList!= 0)
---
>             if ( !listSaveAuList.empty() )
349c228
<                 pApp->m_zoneList->current = (LIST_REC *)listSaveZoneList;
---
>                 auList = listSaveAuList;
351d229
<             zone = (ZONE *)List::next(pApp->m_zoneList);
353c231
<         if (TransferPerformed==false)
---
>         if ( !listSaveZoneList.empty() )
355c233
<             fprintf(pApp->m_pFileTransfer, "\n%4d No transfers", period);
---
>             pApp->m_zoneList = listSaveZoneList;
356a235,238
>         if (TransferPerformed == false)
>         {
>             fprintf(pApp->m_pFileTransfer, "\n%4d No transfers", pApp->m_currentPeriod);
>         }
