void
AttributesImpl::addAttribute(
			const XMLCh*	uri,
			const XMLCh*	localName,
			const XMLCh*	name,
			const XMLCh*	type,
			const XMLCh*	value)
{
	assert(name != 0);
	assert(type != 0);
	assert(value != 0);

	typedef AttributeVectorEntry::XMLChVectorType	XMLChVectorType;

	if (m_attributesVector.capacity() == 0)
	{
		m_attributesVector.reserve(eDefaultVectorSize);
	}

    typedef XalanMemMgrAutoPtr<AttributeVectorEntryExtended,true> AutoPtr;

	AutoPtr	theEntry(getMemoryManager(), getNewEntry(name, type, value, uri, localName));

	// Add the new one.
	m_attributesVector.push_back(theEntry.get());

	theEntry.release();
}
void ChangeList::addSubRefd(const UInt32 uiContainerId,
                                  bool   ignoreLevel  )
{
#ifdef OSG_ENABLE_VALGRIND_CHECKS
    VALGRIND_CHECK_VALUE_IS_DEFINED(uiContainerId);
#endif

#ifndef SILENT
    fprintf(stderr, "Add SubRef %u\n", uiContainerId);
#endif

    if(_bReadOnly == true)
        return;

    ContainerChangeEntry *pEntry = getNewEntry();

    if(_iSubRefLevel == 0 || ignoreLevel == true)
    {
        pEntry->uiEntryDesc   = ContainerChangeEntry::SubReference;
    }
    else
    {
        pEntry->uiEntryDesc   = ContainerChangeEntry::DepSubReference;
    }

    pEntry->uiContainerId = uiContainerId;
    pEntry->pList         = this;
}
OSG_BEGIN_NAMESPACE

#define SILENT
#define SILENT_CPTR

#if 1
void ChangeList::addAddRefd(const UInt32 uiContainerId)
{
#ifdef OSG_ENABLE_VALGRIND_CHECKS
    VALGRIND_CHECK_VALUE_IS_DEFINED(uiContainerId);
#endif

#ifndef SILENT
    fprintf(stderr, "Add AddRef %u\n",
            uiContainerId);
#endif

    if(_bReadOnly == true)
        return;

    ContainerChangeEntry *pEntry = getNewEntry();

    pEntry->uiEntryDesc   = ContainerChangeEntry::AddReference;
    pEntry->uiContainerId = uiContainerId;
    pEntry->pList         = this;
}
void ChangeList::merge(ChangeList &other)
{
    ChangedStoreConstIt cIt  = other._createdStore.begin();
    ChangedStoreConstIt cEnd = other._createdStore.end  ();

    while(cIt != cEnd)
    {
        ContainerChangeEntry *pEntry = getNewCreatedEntry();

        pEntry->uiEntryDesc   = ContainerChangeEntry::Create;
        pEntry->uiContainerId = (*cIt)->uiContainerId;

        ++cIt;
    }

    cIt  = other._changedStore.begin();
    cEnd = other._changedStore.end  ();

    while(cIt != cEnd)
    {
        if((*cIt)->uiEntryDesc == ContainerChangeEntry::AddReference   ||
           (*cIt)->uiEntryDesc == ContainerChangeEntry::SubReference   ||
           (*cIt)->uiEntryDesc == ContainerChangeEntry::DepSubReference )
        {
            ContainerChangeEntry *pEntry = getNewEntry();
     
            pEntry->uiEntryDesc   = (*cIt)->uiEntryDesc;
            pEntry->uiContainerId = (*cIt)->uiContainerId;
            pEntry->pList         = this;
        }
        else if((*cIt)->uiEntryDesc == ContainerChangeEntry::Change)
        {
            ContainerChangeEntry *pEntry = getNewEntry();
            
            pEntry->uiEntryDesc   = ContainerChangeEntry::Change;
            pEntry->pFieldFlags   = (*cIt)->pFieldFlags;
            pEntry->uiContainerId = (*cIt)->uiContainerId;
            pEntry->whichField    = (*cIt)->whichField;
            pEntry->pList         = this;
        }

        ++cIt;
    }
}
AttributesImpl&
AttributesImpl::operator=(const AttributesImpl&		theRHS)
{
	if (this != &theRHS)
	{
		// Note that we can't chain up to our base class operator=()
		// because it's private.

		// Some temporary structures to hold everything
		// until we're done.
		AttributesVectorType		tempVector(getMemoryManager());

		const unsigned int	theLength = theRHS.getLength();

		if (theLength > 0)
		{
			// Reserve the appropriate capacity right now...
			tempVector.reserve(theLength);

			// This will delete everything in tempVector when we're done...
			CollectionDeleteGuard<AttributesVectorType,
								  DeleteFunctor<AttributeVectorEntryExtended> >		theGuard(tempVector);

			typedef AttributesVectorType::const_iterator		const_iterator;

			const const_iterator	theEnd = theRHS.m_attributesVector.end();

			// Copy the vector entries, and build the index map...
			for(const_iterator i = theRHS.m_attributesVector.begin(); i != theEnd; ++i)
			{
				AttributeVectorEntryExtended* const		theEntry = *i;

				assert(theEntry != 0);

				// Add the item...
				tempVector.push_back(
					getNewEntry(
						&*theEntry->m_Name.begin(),
						&*theEntry->m_Type.begin(),
						&*theEntry->m_Value.begin(),
						&*theEntry->m_uri.begin(),
						&*theEntry->m_localName.begin()));
			}

			// OK, we're safe, so swap the contents of the
			// containers.  This is guaranteed not to throw.
			m_attributesVector.swap(tempVector);
		}

		assert(getLength() == theLength);
	}

	return *this;
}
void main(){
	////////////////Data fields //////////////////////////////////////////////
	/*******************Data loaded from files*/
	const int CAP = 150; // Capacity of each month's file.
	//store user date entries, loaded from each month's file
	int dayArr[CAP];
	int cataCodeArr[CAP];
	double amountArr[CAP];
	// loaded from the same file as user data entries, at beginning of file
	double monthBudget;

	// store each day's spending, for display on calendar, loaded from another file
	const int DAY366 = 366; 
	double dailySpendInYear[DAY366]; 

	/*********************Data created at run time*/
	const string DATA_FILE_NAME[] = {"JanuaryData.txt", "FebruaryData.txt", "MarchData.txt", "AprilData.txt",
		"MayData.txt", "JuneData.txt", "JulyData.txt", "AuguestData.txt", "SeptemberData.txt", "OctoberData.txt",
		"NovemberData.txt", "DecemberData.txt" };

	//controller 
	bool exit = false;
	int choice;

	//intermedia 
	int currentMonth, currentDay;
	int entryDate, entryCode;
	double entryAmount;
	double budget = 0, currentBalance = 0, currentTotalSpend = 0;
	int numOfEntries;
	int firstDayOfMonthYearIndex;

	const int MAX_DAYS_IN_MONTH = 31;
	double dailySumArr[MAX_DAYS_IN_MONTH];
	const int NUM_OF_CATAGORY = 4;
	double catagorySumArr[NUM_OF_CATAGORY];


	//////////////////Title & Banner////////////////////////////////////////
	system("title Where Did Your Dollar Go? by Hanfei Xu");

	const int MAX_LENGTH = 90;
	string banner[] = {
		"CIT120 Final Project",
		"Daily Spending Tracker",
		"by Hanfei Xu",
		""
	};
	printBanner(banner, MAX_LENGTH);
	
	///////////////////UI //////////////////////////////////////////////////

	printCenterLine("Welcom to your money tracker \n", MAX_LENGTH);
	printCenterLine("May I know what month this is (Input numberice month #) ?", MAX_LENGTH);
	printCenterLine("Only April (4) has data right now.", MAX_LENGTH);
	for (int i = 0; i < 12; ++i){
		if (i % 6 == 0)
			cout << "\n\t";
		cout << i + 1 << " " << MONTH_NAME[i] << ", ";		
	}
	cout << "\n";
	currentMonth = getIntRange(1, 12);

	initDailySum(dailySumArr, MAX_DAYS_IN_MONTH);
	
	fstream monthData;
	monthData.open(DATA_FILE_NAME[currentMonth - 1], ios::in);
	if (!monthData){ // if user try to start a new month

		//create new month data file
		monthData.close();
		monthData.open(DATA_FILE_NAME[currentMonth - 1], ios::out);
		//set budget
		cout << "\nYou started a NEW month. Please set your budget (you can change that later): ";
		budget = getDbGreater(0);
		currentBalance = budget;
		numOfEntries = 0;
		monthData.close();
	}
	else { // if user stays in old month
		//load budget, entries,from file
		numOfEntries = loadMonthData(monthData, budget, dayArr, cataCodeArr, amountArr, CAP);
		monthData.close();

		//calculate daily spending, totalspending, balance
		calcDailySum(dayArr, amountArr, numOfEntries, dailySumArr, MAX_DAYS_IN_MONTH);
		currentTotalSpend = calcTotalSpending(dailySumArr, MAX_DAYS_IN_MONTH);
		currentBalance = budget - currentTotalSpend;

		// Print monthly overview
		printMonthlyCalendar(currentMonth, dailySumArr);
		cout << "\n"
			<< "Budget: " << budget << "\n"
			<< "Balance: " << currentBalance << "\n\n";
		
	}

	while (exit == false){
		dispMainMenu();
		choice = getIntRange(1, 6);

		switch (choice)
		{
		case 1: getNewEntry(currentMonth, entryDate, entryCode, entryAmount);
				addEntry(dayArr, cataCodeArr, amountArr, numOfEntries, CAP, entryDate, entryCode, entryAmount);
				// refresh running data
				initDailySum(dailySumArr, MAX_DAYS_IN_MONTH);
				calcDailySum(dayArr, amountArr, numOfEntries, dailySumArr, MAX_DAYS_IN_MONTH);
				currentTotalSpend = calcTotalSpending(dailySumArr, MAX_DAYS_IN_MONTH);
				currentBalance = budget - currentTotalSpend;
				break;

		case 2: changeBudget(budget, getNewBugdet()); 
				currentBalance = budget - currentTotalSpend; 
				break;

		case 3: printMonthlyCalendar(currentMonth, dailySumArr); 
				cout << "\n"
					<< "Budget: " << budget << "\n"
					<< "Balance: " << currentBalance << "\n\n";
				break;

		case 4: printMonthlyCalendar(currentMonth, dailySumArr);
				cout << "\n"
				<< "Budget: " << budget << "\n"
				<< "Balance: " << currentBalance << "\n\n";
				initCataSum(catagorySumArr, NUM_OF_CATAGORY);
				calcCataSum(cataCodeArr, amountArr, numOfEntries, catagorySumArr, NUM_OF_CATAGORY);
				printHistogramH(catagorySumArr, NUM_OF_CATAGORY, 10,"$", "Type");
				printHistogramH(dailySumArr, NUM_OF_DAYS_MONTH[currentMonth - 1], 5 ,"$", "Date");
				break;
		case 5: cout << "\n Under Construction \n";  break;
		case 6: 
				fstream file;
				file.open(DATA_FILE_NAME[currentMonth - 1], ios::out);
				writeMonthData(file, budget, dayArr, cataCodeArr, amountArr, numOfEntries);
				file.close();
			    exit = true;
				break;
		
		}
		
		cout << "\nPress ENTER to continue";
		cin.get();
		system("cls");
	}
	
}