package com.jlabar.runstats;

import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.TableLayout.LayoutParams;
import android.widget.TextView;

import com.jlabar.runstats.dal.DataStore;
import com.jlabar.runstats.dal.IDataStore;
import com.jlabar.runstats.domain.IRunActivity;
import com.jlabar.runstats.domain.ToastShower;
import com.jlabar.runstats.domain.accumulators.AvgDistanceAccumulator;
import com.jlabar.runstats.domain.accumulators.AvgDurationAccumulator;
import com.jlabar.runstats.domain.accumulators.AvgPaceAccumulator;
import com.jlabar.runstats.domain.accumulators.CountAccumulator;
import com.jlabar.runstats.domain.accumulators.IAccumulator;
import com.jlabar.runstats.domain.accumulators.SpeedAccumulator;
import com.jlabar.runstats.domain.accumulators.TotalDistanceAccumulator;
import com.jlabar.runstats.domain.accumulators.TotalDurationAccumulator;
import com.jlabar.runstats.domain.groups.IGroup;
import com.jlabar.runstats.domain.order.GroupOrderer;
import com.jlabar.runstats.domain.order.IGroupComparator;
import com.jlabar.runstats.domain.order.ReverseGroupOrderer;
import com.jlabar.runstats.domain.order.ReverseValueOrderer;
import com.jlabar.runstats.domain.order.ValueOrderer;
import com.jlabar.runstats.domain.sorters.DayOfMonthSorter;
import com.jlabar.runstats.domain.sorters.DayOfWeekSorter;
import com.jlabar.runstats.domain.sorters.HourOfDaySorter;
import com.jlabar.runstats.domain.sorters.IGroupSorter;
import com.jlabar.runstats.domain.sorters.MonthSorter;
import com.jlabar.runstats.domain.sorters.TotalSorter;
import com.jlabar.runstats.domain.sorters.WeekSorter;
import com.jlabar.runstats.domain.sorters.YearSorter;

public class GraphActivity extends Activity
{
	private static final String _titleFormat = "RunStats   |   %s, %s";
	
	private final SparseArray<IGroupComparator> _ordererMap = new SparseArray<IGroupComparator>() 
	{
		{ 
			put(R.id.menu_item_order_group, new GroupOrderer()); 
			put(R.id.menu_item_order_group_rev, new ReverseGroupOrderer());  
			put(R.id.menu_item_order_value, new ValueOrderer()); 
			put(R.id.menu_item_order_value_rev, new ReverseValueOrderer()); 
		}
	};
	
	private final SparseArray<IGroupSorter> _sorterMap = new SparseArray<IGroupSorter>() 
	{
		{ 
			put(R.id.menu_item_total_stats, new TotalSorter()); 
			put(R.id.menu_item_yearly, new YearSorter());  
			put(R.id.menu_item_monthly, new MonthSorter()); 
			put(R.id.menu_item_weekly, new WeekSorter()); 
			put(R.id.menu_item_hour_day, new HourOfDaySorter()); 
			put(R.id.menu_item_day_week, new DayOfWeekSorter()); 
			put(R.id.menu_item_day_month, new DayOfMonthSorter()); 
		}
	};

	private final SparseArray<IAccumulator> _accumulatorMap = new SparseArray<IAccumulator>() 
	{
		{ 
			put(R.id.menu_item_avg_distance, new AvgDistanceAccumulator()); 
			put(R.id.menu_item_total_distance, new TotalDistanceAccumulator()); 
			put(R.id.menu_item_avg_duration, new AvgDurationAccumulator()); 
			put(R.id.menu_item_total_duration, new TotalDurationAccumulator()); 
			put(R.id.menu_item_number, new CountAccumulator()); 
			put(R.id.menu_item_speed, new SpeedAccumulator()); 
			put(R.id.menu_item_pace, new AvgPaceAccumulator()); 
		}
	};
	
	private List<IGroup> _groups;
	private Context _context;
	private IDataStore _dataStore;
	private List<IRunActivity> _activityCache;
	private IAccumulator _currentAccumulator;
	private IGroupSorter _currentSorter;
	private IGroupComparator _currentOrderer;
	private BarChart _chart;
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.graph_activity);

		_groups = new ArrayList<IGroup>();
		_activityCache = new ArrayList<IRunActivity>();
		_currentAccumulator = _accumulatorMap.get(R.id.menu_item_total_distance);
		_currentSorter = _sorterMap.get(R.id.menu_item_monthly);
		_currentOrderer = _ordererMap.get(R.id.menu_item_order_group);
		
		_chart = new BarChart(this);
		LinearLayout view = (LinearLayout)findViewById(R.id.chart);
		view.addView(_chart);
		_chart.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		
		displayData();
		
		_context = getApplicationContext();
		_dataStore = new DataStore(new ToastShower(this), _context, new Logger(_context));
		
		ActionBar actionBar = getActionBar();
		actionBar.setHomeButtonEnabled(true);
		actionBar.setDisplayHomeAsUpEnabled(true);	
	}
	
	private void displayData()  
	{
		_chart.update(_currentAccumulator, _currentSorter, _currentOrderer, _groups);
		
		String title = String.format(_titleFormat, _currentAccumulator.getDescription(), _currentSorter.getDescription());
		setTitle(title);
		
		String value = "";
		
		for (int i = 0; i < _groups.size(); i++)
		{
			IGroup g = _groups.get(i);
			value += g.getDescription() + ": " + _currentAccumulator.getDisplayValue(g.getValue()) + "\n";
		}
		
		((TextView)findViewById(R.id.TMP_group_display)).setText(value);
	}

	@Override 
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.stats_activity_actionbar_menu, menu);
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
		case android.R.id.home:
			
			Intent intent = new Intent(this, RunStatsActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
			return true;
		
		case R.id.menu_item_order_group:
		case R.id.menu_item_order_group_rev:
		case R.id.menu_item_order_value:
		case R.id.menu_item_order_value_rev:
			
			_currentOrderer = _ordererMap.get(item.getItemId());
			reOrder();
			
			displayData();
			return true;
			
		case R.id.menu_item_avg_distance:
		case R.id.menu_item_total_distance:
		case R.id.menu_item_avg_duration:
		case R.id.menu_item_total_duration:
		case R.id.menu_item_number:
		case R.id.menu_item_speed:
		case R.id.menu_item_pace:
			
			_currentAccumulator = _accumulatorMap.get(item.getItemId());
			
			reAccumulate();
			reOrder();

			displayData();
			return true;
			
		case R.id.menu_item_day_month:
		case R.id.menu_item_day_week:
		case R.id.menu_item_monthly:
		case R.id.menu_item_weekly:
		case R.id.menu_item_hour_day:
		case R.id.menu_item_total_stats:
		case R.id.menu_item_yearly:
			
			_currentSorter = _sorterMap.get(item.getItemId());
			
			reSort();
			reAccumulate();
			reOrder();
			
			displayData();
			return true;
		
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override 
	public void onStart()
	{		
		super.onStart();
		if (_dataStore.open())
		{		
			_activityCache = _dataStore.loadActivities();
			reSort();
			reAccumulate();
			reOrder();
			displayData();
		}
	}

	@Override
	protected void onStop()
	{
		_dataStore.close();
		super.onStop();
	}
	
	private void reAccumulate()
	{
		for (IGroup g : _groups)
		{
			g.accumulate(_currentAccumulator);
		}
	}

	private void reOrder()
	{
		Util.sort(_groups, _currentOrderer);
	}

	private void reSort()
	{
		_groups = _currentSorter.sort(_activityCache);
	}
}
