void BudgetWindow::GenerateBudget(const bool &zero)
{
	// Generate a budget based on the last year's transactions
	ReportGrid income(1,0), spending(1,0);

	gDatabase.DBCommand("delete from budgetlist",
						"BudgetWindow::GenerateBudget:empty budget");

	CppSQLite3Query query;
	query = gDatabase.DBQuery("select * from categorylist order by name",
							"BudgetWindow::GenerateBudget:get categories");

	if(query.eof())
		return;

	float maxwidth=fCategoryList->StringWidth(TRANSLATE("Category"));
	while(!query.eof())
	{
		BString catname = DeescapeIllegalCharacters(query.getStringField(0));

		if(catname.ICompare(TRANSLATE("Transfer"))==0)
		{
			query.nextRow();
			continue;
		}

		bool isexpense = !query.getIntField(1);

		if(isexpense)
		{
			spending.AddItem();
			spending.SetRowTitle(spending.CountItems()-1,catname.String());
		}
		else
		{
			income.AddItem();
			income.SetRowTitle(income.CountItems()-1,catname.String());
		}
		float tempwidth = fCategoryList->StringWidth(catname.String());
		maxwidth = MAX(maxwidth,tempwidth);
		query.nextRow();
	}

	query.finalize();

	// Now that we have the list of categories, query for transactions for each
	// account from each category

	BString querystring;
	Fixed cattotal;
	for(int32 i=0; i<income.CountItems(); i++)
	{
		querystring = "";
		cattotal = 0;

		if(!zero)
		{
			for(int32 j=0; j<gDatabase.CountAccounts(); j++)
			{
				Account *acc = gDatabase.AccountAt(j);
				querystring = "select sum(amount) from account_" ;
				querystring << acc->GetID()	<< " where category = '"
							<< EscapeIllegalCharacters(income.RowTitle(i))
							<< "' and date > " << DecrementDateByYear(GetCurrentDate()) << ";";
				query = gDatabase.DBQuery(querystring.String(),
										"BudgetWindow::GenerateBudget:get category");
				cattotal.AddPremultiplied(query.getInt64Field(0));
				query.finalize();
			}
			cattotal /= 12;
			cattotal.Round();
		}
		income.SetValue(0,i,cattotal);
		gDatabase.AddBudgetEntry(BudgetEntry(income.RowTitle(i),cattotal,BUDGET_MONTHLY,false));
	}

	for(int32 i=0; i<spending.CountItems(); i++)
	{
		querystring = "";
		cattotal = 0;

		if(!zero)
		{
			for(int32 j=0; j<gDatabase.CountAccounts(); j++)
			{
				Account *acc = gDatabase.AccountAt(j);
				querystring = "select sum(amount) from account_" ;
				querystring << acc->GetID()	<< " where category = '"
							<< EscapeIllegalCharacters(spending.RowTitle(i))
							<< "';";
				query = gDatabase.DBQuery(querystring.String(),
										"BudgetWindow::GenerateBudget:get category");
				cattotal.AddPremultiplied(query.getInt64Field(0));
				query.finalize();
			}
			cattotal /= 12;
			cattotal.Round();
		}
		spending.SetValue(0,i,cattotal);
		gDatabase.AddBudgetEntry(BudgetEntry(spending.RowTitle(i),cattotal,BUDGET_MONTHLY,true));
	}
}
void BudgetWindow::MessageReceived(BMessage *msg)
{
	switch(msg->what)
	{
		case M_SELECT_CATEGORY:
		{
			HandleCategorySelection();
			fAmountBox->MakeFocus(true);
			break;
		}
		case M_AMOUNT_CHANGED:
		{
			BString str(fAmountBox->Text());
			if(str.CountChars()<1)
				str = "0";

			Fixed f;
			if(gDefaultLocale.StringToCurrency(str.String(),f)!=B_OK)
				break;
			f.Round();
			gDefaultLocale.CurrencyToString(f,str);
			str.Truncate(str.FindFirst(gDefaultLocale.CurrencyDecimal()));
			str.RemoveFirst(gDefaultLocale.CurrencySymbol());

			BRow *row = fCategoryList->CurrentSelection();
			if(!row)
				break;

			row->SetField(new BStringField(str.String()),1);
			fCategoryList->UpdateRow(row);

			BudgetEntry entry;
			gDatabase.GetBudgetEntry( ((BStringField*)row->GetField(0))->String(),entry );
			entry.amount = f;
			if(entry.isexpense)
				entry.amount.Invert();
			gDatabase.AddBudgetEntry(entry);

			RefreshBudgetGrid();
			RefreshBudgetSummary();

			fBudgetSummary->SetFocusRow( entry.isexpense ? 1 : 0);
			fBudgetSummary->SetFocusRow(2);
			break;
		}
		case M_BUDGET_RECALCULATE:
		{
			GenerateBudget(false);
			RefreshBudgetGrid();
			RefreshBudgetSummary();
			RefreshCategories();
			break;
		}
		case M_BUDGET_ZERO:
		{
			GenerateBudget(true);
			RefreshBudgetGrid();
			RefreshBudgetSummary();
			RefreshCategories();
			break;
		}
		case M_SET_PERIOD_MONTH:
		{
			SetPeriod(BUDGET_MONTHLY);
			break;
		}
		case M_SET_PERIOD_WEEK:
		{
			SetPeriod(BUDGET_WEEKLY);
			break;
		}
		case M_SET_PERIOD_QUARTER:
		{
			SetPeriod(BUDGET_QUARTERLY);
			break;
		}
		case M_SET_PERIOD_YEAR:
		{
			SetPeriod(BUDGET_ANNUALLY);
			break;
		}
		case M_NEXT_FIELD:
		{
			if(fAmountBox->ChildAt(0)->IsFocus())
				fMonthly->MakeFocus(true);
			break;
		}
		case M_PREVIOUS_FIELD:
		{
			if(fAmountBox->ChildAt(0)->IsFocus())
				fCategoryList->MakeFocus(true);
			break;
		}
		default:
			BWindow::MessageReceived(msg);
	}
}