gt: 			monthStr = "0"+ monthStr;
context: package ru.orangesoftware.financisto2.activity;
  
  import android.app.ListActivity;
  import android.content.Intent;
  import android.graphics.Color;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.ImageButton;
  import android.widget.TextView;
  import ru.orangesoftware.financisto2.R;
  import ru.orangesoftware.financisto2.adapter.CreditCardStatementAdapter;
  import ru.orangesoftware.financisto2.db.DatabaseAdapter;
  import ru.orangesoftware.financisto2.db.DatabaseAdapter_;
  import ru.orangesoftware.financisto2.model.*;
  import ru.orangesoftware.financisto2.utils.MonthlyViewPlanner;
  import ru.orangesoftware.financisto2.utils.PinProtection;
  import ru.orangesoftware.financisto2.utils.TransactionList;
  import ru.orangesoftware.financisto2.utils.Utils;
  
  import java.text.SimpleDateFormat;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.GregorianCalendar;
  import java.util.List;
  
  /**
   * Display the credit card bill, including scheduled and future transactions for a given period.
   * Display only expenses, ignoring payments (positive values) in Credit Card accounts. 
   * @author Abdsandryk
   */
  public class MonthlyViewActivity extends ListActivity {
  	
      public static final String ACCOUNT_EXTRA = "account_id";
      public static final String BILL_PREVIEW_EXTRA = "bill_preview";
  
  	private DatabaseAdapter db;
  
  	private long accountId = 0;
      private Account account;
      private Currency currency;
  	private boolean isCreditCard = false;
  	private boolean isStatementPreview = false;
  	
  	private String title;
  	private int closingDay = 0;
  	private int paymentDay = 0;
  
      private int month = 0;
      private int year = 0;
      private Calendar closingDate;
  
  	private Utils u;
  
      private MonthlyPreviewTask currentTask;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.monthly_view);
          
          u = new Utils(this);
  
          Intent intent = getIntent();
  		if (intent != null) {
  			accountId = intent.getLongExtra(ACCOUNT_EXTRA, 0);
  			isStatementPreview = intent.getBooleanExtra(BILL_PREVIEW_EXTRA, false);
  		}
  		initialize();
      }
      
      @Override
      public void onDestroy() {
          cancelCurrentTask();
      	super.onDestroy();
      }
  
      private void cancelCurrentTask() {
          if (currentTask != null) {
              currentTask.cancel(true);
              currentTask = null;
          }
      }
  
      @Override
  	protected void onPause() {
  		super.onPause();
  		PinProtection.lock(this);
  	}
  
  	@Override
  	protected void onResume() {
  		super.onResume();
  		PinProtection.unlock(this);
  	}
      
      
      /**
       * Initialize data and GUI elements.
       */
      private void initialize() {
      	
      	// get account data
          db = DatabaseAdapter_.getInstance_(this);
  
  		// set currency based on account
          account = db.getAccount(accountId);
  		
          if (month==0 && year==0) {
  	        // get current month and year in first launch
  			Calendar cal = Calendar.getInstance();
  			month = cal.get(Calendar.MONTH) + 1;
  			year = cal.get(Calendar.YEAR);
          }
  		
  		// set part of the title, based on account name: "<CCARD> Bill"
  		if (account != null) {
  			
  			// get account type
  			isCreditCard = AccountType.valueOf(account.type).isCreditCard;
  	
  			currency = account.currency;
  			
  			if (isCreditCard) {
  				if (isStatementPreview) { 
  					// assuming that expensesOnly is true only if payment and closing days > 0 [BlotterActivity]
  					title = getString(R.string.ccard_statement_title);
  					String accountTitle = account.title;
  					if (account.title==null || account.title.length()==0) {
  						accountTitle = account.cardIssuer;
  					}
  					String toReplace = getString(R.string.ccard_par);
  					title = title.replaceAll(toReplace, accountTitle);
  					paymentDay = account.paymentDay;
  					closingDay = account.closingDay;
  					// set activity window title
  					this.setTitle(R.string.ccard_statement);
  					setCCardTitle();
  					setCCardInterval();
  				} else {
  					title = (account.title==null|| account.title.length()==0? account.cardIssuer: account.title);
  					paymentDay = 1;
  					closingDay = 31;
  					setTitle();
  					setInterval();
  					
  					// set payment date and label on total bar
  					TextView totalLabel = (TextView) findViewById(R.id.monthly_result_label);
  					totalLabel.setText(getResources().getString(R.string.monthly_result));
  				}
  			} else {
  				if (account.title==null|| account.title.length()==0) {
  					if (isCreditCard) {
  						// title = <CARD_ISSUER>
  						title = account.cardIssuer;
  					} else {
  						// title = <ACCOUNT_TYPE_TITLE>
  						AccountType type = AccountType.valueOf(account.type);
  						title = getString(type.titleId);
  					}
  				} else {
  					// title = <TITLE>
  					title = account.title;
  				}
  				
  				paymentDay = 1;
  				closingDay = 31;
  				setTitle();
  				setInterval();
  				
  				// set payment date and label on total bar
  				TextView totalLabel = (TextView) findViewById(R.id.monthly_result_label);
  				totalLabel.setText(getResources().getString(R.string.monthly_result));
  			}
  
              ImageButton bPrevious = (ImageButton) findViewById(R.id.bt_month_previous);
  			bPrevious.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View arg0) {
                      month--;
                      if (month < 1) {
                          month = 12;
                          year--;
                      }
                      if (isCreditCard) {
                          if (isStatementPreview) {
                              setCCardTitle();
                              setCCardInterval();
                          } else {
                              setTitle();
                              setInterval();
                          }
                      } else {
                          setTitle();
                          setInterval();
                      }
                  }
              });
  
              ImageButton bNext = (ImageButton) findViewById(R.id.bt_month_next);
  			bNext.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View arg0) {
                      month++;
                      if (month > 12) {
                          month = 1;
                          year++;
                      }
                      if (isCreditCard) {
                          if (isStatementPreview) {
                              setCCardTitle();
                              setCCardInterval();
                          } else {
                              setTitle();
                              setInterval();
                          }
                      } else {
                          setTitle();
                          setInterval();
                      }
                  }
              });
  		
  		}
  	}
  
      /**
       * Configure the interval based on the bill period of a credit card.
       * Attention: 
       *   Calendar.MONTH = 0 to 11
       *   integer  month = 1 to 12
       */
  	private void setCCardInterval() {
  		
  		Calendar close = getClosingDate(month, year);
  		Calendar open;
  		
  		if (month>1) {
  			// closing date from previous month
  			open = getClosingDate(month-1, year);
  		} else {
  			open = getClosingDate(12, year-1);
  		}
  		// add one day to the closing date of previous month
  		open.add(Calendar.DAY_OF_MONTH, +1);
  		
  		// adjust time for closing day
  		close.set(Calendar.HOUR_OF_DAY, 23);
  		close.set(Calendar.MINUTE, 59);
  		close.set(Calendar.SECOND, 59);
  		
  		this.closingDate = new GregorianCalendar(close.get(Calendar.YEAR), 
  				  								 close.get(Calendar.MONTH),
  				  								 close.get(Calendar.DAY_OF_MONTH));
  		
  		// Verify custom closing date
  		int periodKey = Integer.parseInt(Integer.toString(close.get(Calendar.MONTH))+
  					 	Integer.toString(close.get(Calendar.YEAR)));
  		
  		int cd = db.getCustomClosingDay(accountId, periodKey);
  		if (cd>0) {
  			// use custom closing day
  			close.set(Calendar.DAY_OF_MONTH, cd);
  		}
  		
  		// Verify custom opening date = closing day of previous month + 1
  		periodKey = Integer.parseInt(Integer.toString(open.get(Calendar.MONTH))+
  				 	Integer.toString(open.get(Calendar.YEAR)));
  		
  		int od = db.getCustomClosingDay(accountId, periodKey);
  		if (od>0) {
  			// use custom closing day
  			open.set(Calendar.DAY_OF_MONTH, od);
  			open.add(Calendar.DAY_OF_MONTH, +1);
  		}
  		
  		fillData(open, close);
  	}
  	
      /**
       * Configure the interval in a monthly perspective.
       * Attention: 
       *   Calendar.MONTH = 0 to 11
       *   integer  month = 1 to 12
       */
  	private void setInterval() {
  		
  		Calendar close = new GregorianCalendar(year, month-1, getLastDayOfMonth(month, year));
  		Calendar open = new GregorianCalendar(year, month-1, 1);
  		
  		// adjust time for closing day
  		close.set(Calendar.HOUR_OF_DAY, 23);
  		close.set(Calendar.MINUTE, 59);
  		close.set(Calendar.SECOND, 59);
          close.set(Calendar.MILLISECOND, 999);
  		
  		fillData(open, close);
  	}
  	
  	 // Returns the day on which the credit card bill closes for a given month/year.
  	private Calendar getClosingDate(int month, int year) {
  		int m = month;
  		if (closingDay > paymentDay) {
  			m--;
  		}
  		int maxDay = getLastDayOfMonth(m, year);
  		int day = closingDay;
  		if (closingDay>maxDay) {
  			day = maxDay;
  		}
  		
  		return new GregorianCalendar(year, m-1, day);
  	}
  	
  	private int getLastDayOfMonth(int month, int year) {
  		Calendar calCurr = GregorianCalendar.getInstance();
  		calCurr.set(year, month-1, 1); // Months are 0 to 11
  		return calCurr.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);
  	}
  
      private class MonthlyPreviewTask extends AsyncTask<Void, Void, TransactionList> {
  
          private final Date open;
          private final Date close;
          private final Date now;
  
          private MonthlyPreviewTask(Date open, Date close, Date now) {
              this.open = open;
              this.close = close;
              this.now = now;
          }
  
          @Override
          protected void onPreExecute() {
              ((TextView)findViewById(android.R.id.empty)).setText(R.string.calculating);
          }
  
          @Override
          protected TransactionList doInBackground(Void... voids) {
              MonthlyViewPlanner planner = new MonthlyViewPlanner(db, account, isStatementPreview, open, close, now);
              TransactionList transactions;
              if (isStatementPreview) {
                  transactions = planner.getCreditCardStatement();
              } else {
                  transactions = planner.getPlannedTransactionsWithTotals();
              }
              return transactions;
          }
  
          @Override
          protected void onPostExecute(TransactionList monthlyPreviewReport) {
              List<TransactionInfo> transactions = monthlyPreviewReport.transactions;
              long total = monthlyPreviewReport.totals[0].balance;
              if (transactions == null || transactions.isEmpty()) {
                  displayNoTransactions();
              } else { // display data
  
                  // Mapping data to view
                  CreditCardStatementAdapter expenses = new CreditCardStatementAdapter(MonthlyViewActivity.this, R.layout.credit_card_transaction, transactions, currency, accountId);
                  expenses.setStatementPreview(isStatementPreview);
                  setListAdapter(expenses);
  
                  // calculate total
                  // display total
                  TextView totalText = (TextView)findViewById(R.id.monthly_result);
                  if (isStatementPreview) {
                      u.setAmountText(totalText, currency, (-1)*total, false);
                      totalText.setTextColor(Color.BLACK);
                  } else {
                      if (total<0) {
                          u.setAmountText(totalText, currency, (-1)*total, false);
                          u.setNegativeColor(totalText);
                      } else {
                          u.setAmountText(totalText, currency, total, false);
                          u.setPositiveColor(totalText);
                      }
                  }
              }
          }
      }
  
  	/**
  	 * Get data for a given period and display the related credit card expenses.
  	 * @param open Start of period.
  	 * @param close End of period.
  	 */
  	private void fillData(Calendar open, Calendar close) {
          cancelCurrentTask();
          currentTask = new MonthlyPreviewTask(open.getTime(), close.getTime(), new Date());
          currentTask.execute();
      }
  
      private void displayNoTransactions() {
          TextView totalText = (TextView)findViewById(R.id.monthly_result);
          // display total = 0
          u.setAmountText(totalText, currency, 0, false);
          totalText.setTextColor(Color.BLACK);
          // hide list and display empty message
          ((TextView)findViewById(android.R.id.empty)).setText(R.string.no_transactions);
          setListAdapter(null);
      }
  
      /**
  	 * Adjust the title based on the credit card's payment day.
  	 */
  	private void setCCardTitle() {
  		
  		Calendar date = new GregorianCalendar(year, month-1, paymentDay);
  
          String monthStr = Integer.toString(date.get(Calendar.MONTH) + 1);
          String yearStr = Integer.toString(date.get(Calendar.YEAR));
  
          String paymentDayStr;
          if (paymentDay < 10) {
          	paymentDayStr = "0"+paymentDay;
          } else {
          	paymentDayStr = Integer.toString(paymentDay);
          }
  		
  		if (monthStr.length()<2) {
  