package com.ethostream.ethoandroid;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.FilterQueryProvider;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleCursorAdapter.CursorToStringConverter;

public class SelectProperty extends Activity
{
    final static int[] to = new int[] { android.R.id.text1 };
    final static String[] from = new String[] { "PropertyName" };

    private AutoCompleteTextView propertyList;
    private DatabasePropertyAdapter mDbHelper;
    private String propID = null;
    private String username = "";
    
    private static final int ACTIVITY_PROPINFO = 0;
    private static final int ACTIVITY_LOGIN = 1;
    private static final String REMOTE_QUERY_SITE = "http://android.telkonet.com/dbtrips.php";
    
    private static final String TRIPS_TRIPID = "TripID";
    private static final String TRIPS_PROPID = "PropertyID";
    private static final String TRIPS_PROPNAME = "PropertyName";
    private static final String TRIPS_DATES = "Dates";
    private static final String TRIPS_AIRPORTS = "Airports";
    private static final String TRIPS_NOTES = "Notes";
    private static final String TRIPS_FEATURES = "Features";
	private static final int DIALOG_REFRESHDB = 0;
	private static final int DIALOG_CONDITIONAL = 1;
	private static final int DIALOG_INIT_LOAD = 2;
    
    private ArrayList<ContentValues> trips = null;
    private Context context;
    
    @Override
    public void onBackPressed()
    {
       return;
    }
    
    @Override
    protected void onStart() 
    {
    	super.onStart();
    	
    	// load trips here, so they'll refresh every time we see this activity
    	
    	GetTripsAsync getTrips = new GetTripsAsync();
        getTrips.execute();
        try
		{
			trips = getTrips.get();
		} catch (InterruptedException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        ListView tripsList = (ListView) findViewById(R.id.selectproperty_tripslist);
        RowAdapter rowAdapter = new RowAdapter(this, R.layout.selectproperty_item, trips);
		tripsList.setAdapter(rowAdapter);
		
		// OnClickListener for properties derived from trips
        tripsList.setOnItemClickListener(new OnItemClickListener() 
		{
        	public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
        	{
        		// When clicked, launch propinfo for given id
        		switchView(ACTIVITY_PROPINFO, "ID", trips.get(position).getAsString(TRIPS_PROPID));
        	}
		});
        
		
    }

    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        context = this;
        Bundle bundle = getIntent().getExtras();
		if (bundle != null)
		{
			username = bundle.getString("USERNAME");
		}
        
        
        mDbHelper = new DatabasePropertyAdapter(this);
        
        // Check to see if the database has properties in it
        checkProperties();

        setContentView(R.layout.selectproperty);
        
        // used to do trips here
        
        Button confirmButton = (Button) findViewById(R.id.confirm);       
        confirmButton.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View view) 
            {
            	if (propID != null)
            	{
            		// When clicked, launch propinfo for given id
            		switchView(ACTIVITY_PROPINFO, "ID", propID.toString());
            	}
            }
        });

        propertyList = (AutoCompleteTextView) findViewById(R.id.property_name);

        // Create a SimpleCursorAdapter for the properties
        SimpleCursorAdapter adapter = 
            new SimpleCursorAdapter(this, 
                    android.R.layout.simple_dropdown_item_1line, null,
                    from, to);
            
        propertyList.setAdapter(adapter);

        // OnItemClickListener to update values based on selection
        propertyList.setOnItemClickListener(new OnItemClickListener() 
        {
            public void onItemClick(AdapterView<?> listView, View view, int position, long id) 
            {
                Cursor cursor = (Cursor) listView.getItemAtPosition(position);
                String selection = cursor.getString(cursor.getColumnIndexOrThrow("PropertyName"));
                mDbHelper.open();
                cursor = mDbHelper.getProperty(selection);
                cursor.moveToFirst();
                propID = cursor.getString(cursor.getColumnIndex("RemoteID"));
                cursor.close();;
                mDbHelper.close();
            }
        });

        // CursorToStringConverter provides the property names displayed in the AutoCompleteTextView 
        adapter.setCursorToStringConverter(new CursorToStringConverter() 
        {
            public String convertToString(android.database.Cursor cursor) 
            {
                final int columnIndex = cursor.getColumnIndexOrThrow("PropertyName");
                final String str = cursor.getString(columnIndex);
                return str;
            }
        });

        // FilterQueryProvider runs queries for choices that match the specified input
        adapter.setFilterQueryProvider(new FilterQueryProvider() 
        {
            public Cursor runQuery(CharSequence constraint) 
            {
            	mDbHelper.open();
                Cursor cursor = mDbHelper.getMatches((constraint != null ? constraint.toString() : null));
                mDbHelper.close();
                return cursor;
            }
        });
        
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.selectproperty_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.selectproperty_menu_logout:
            switchView(ACTIVITY_LOGIN, "LOGOUT", "LOGOUT");
            return true;
        case R.id.selectproperty_menu_refreshdb:
        	showDialog(DIALOG_REFRESHDB);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    
    private void checkProperties()
    {
    	// Check to see if there are any properties in the database
    	mDbHelper.open();
    	mDbHelper.createPropertyTable();
    	if (mDbHelper.getAll().getCount() == 0)
    	{
    		mDbHelper.close();
    		// There are no properties... go get some
    		showDialog(DIALOG_INIT_LOAD);
    	}
    	mDbHelper.close();
    }
    
    protected Dialog onCreateDialog(int id) 
    {
    	Dialog dialog;
    	AlertDialog.Builder builder;
    	AlertDialog alert;
    	switch(id) 
    	{
    		case DIALOG_REFRESHDB:
    			builder = new AlertDialog.Builder(this);
    			builder.setMessage(this.getString(R.string.dialog_refreshdb_message))
    			.setCancelable(false)
    			.setPositiveButton(this.getString(R.string.dialog_refreshdb_yes), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					//Do something
    					showDialog(DIALOG_CONDITIONAL);
    				}
    			})
    			.setNegativeButton(this.getString(R.string.dialog_refreshdb_no), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					dialog.cancel();
    				}
    			});
    			alert = builder.create();
    			dialog = alert;
    			break;
    		case DIALOG_CONDITIONAL:
    			builder = new AlertDialog.Builder(this);
    			builder.setMessage(this.getString(R.string.dialog_conditional_message))
    			.setCancelable(false)
    			.setPositiveButton(this.getString(R.string.dialog_conditional_yes), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					refreshDatabase(true);
    				}
    			})
    			.setNegativeButton(this.getString(R.string.dialog_conditional_no), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					refreshDatabase(false);
    				}
    			});
    			alert = builder.create();
    			dialog = alert;
    			break;
    		case DIALOG_INIT_LOAD:
    			builder = new AlertDialog.Builder(this);
    			builder.setMessage(this.getString(R.string.dialog_init_load_message))
    			.setCancelable(false)
    			.setPositiveButton(this.getString(R.string.dialog_init_load_yes), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					refreshDatabase(false);
    				}
    			});
    			alert = builder.create();
    			dialog = alert;
    			break;
    		default:
    			dialog = null;
    	}
    	return dialog;
    }
    
    private void refreshDatabase(boolean conditional)
    {
    	RefreshThread rt = new RefreshThread();
    	rt.execute(conditional);
    }
    
	private class RefreshThread extends AsyncTask<Boolean, Void, Void> 
	{
		final ProgressDialog dialog = new ProgressDialog(context);
		@Override
		protected void onPreExecute()
		{
			dialog.setTitle(R.string.selectproperty_resfreshdb_label);
			dialog.setMessage(context.getString(R.string.selectproperty_resfreshdb_message));
			dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			dialog.setMax(2);
			dialog.setProgress(0);
			dialog.show();
		}
		@Override
		protected Void doInBackground(Boolean... params) 
		{
			if (params[0].booleanValue())
			{
				//Conditional
				mDbHelper.open();
				mDbHelper.createPropertyTable();
				ArrayList<ContentValues> remoteList = mDbHelper.getRemotePropertyList(0);
				dialog.setProgress(1);
				if ( mDbHelper.size() < remoteList.size())
				{
					// Our list is smaller, need to refresh
					int currentMax = mDbHelper.getMaxRemoteID();
					ArrayList<ContentValues> missing = mDbHelper.getRemotePropertyList(currentMax);
					dialog.setMax(missing.size());
					for (int i = 0; i < missing.size(); i++)
					{
						mDbHelper.createProperty(missing.get(i));
						dialog.setProgress(i);
					}
					if ( mDbHelper.size() < remoteList.size())
					{
						// List is still smaller. Refresh entire list.
						dialog.setMax(remoteList.size());
						for (int i = 0; i < remoteList.size(); i++)
						{
							mDbHelper.createProperty(remoteList.get(i));
							dialog.setProgress(i);
						}
					}
				}
				else
				{
					dialog.setProgress(2);
				}
				mDbHelper.close();
			}
			else
			{
				//Unconditional
				mDbHelper.open();
				mDbHelper.dropPropertyTable();
				mDbHelper.createPropertyTable();
				ArrayList<ContentValues> remoteList = mDbHelper.getRemotePropertyList(0);
				dialog.setProgress(2);
				dialog.setMax(remoteList.size());
				for (int i = 0; i < remoteList.size(); i++)
				{
					mDbHelper.createProperty(remoteList.get(i));
					dialog.setProgress(i);
				}
				mDbHelper.close();
			}
			return null;
		}
		@Override
		protected void onPostExecute(Void retValue) 
		{
			dialog.dismiss();
		}
	 }
    
    private void switchView(int ACTIVITY, String key, String value)
    {
    	switch(ACTIVITY)
    	{
    		case ACTIVITY_PROPINFO:
    		{
	    		Intent i = new Intent(this, PropTabs.class);
				i.putExtra(key, value);
	        	startActivityForResult(i, ACTIVITY_PROPINFO);
            	break;
    		}
    		case ACTIVITY_LOGIN:
    		{
            	Intent i = new Intent(this, EthoAndroid.class);
            	i.putExtra(key, value);
            	setResult(RESULT_OK, i);
            	finish();
            	break;
    		}
    		default:
    		{
    			break;
    		}
    	}
    }
    
    private class GetTripsAsync extends AsyncTask<Void, Void, ArrayList<ContentValues>>
    {

        ProgressDialog mProgressDialog;
        @Override
        protected void onPostExecute(ArrayList<ContentValues> result) {
            mProgressDialog.dismiss();
        }

        @Override
        protected void onPreExecute() {
            mProgressDialog = ProgressDialog.show(context, "Loading...", "Fetching your current and future trips...");
        }

        @Override
        protected ArrayList<ContentValues> doInBackground(Void... params) 
        {
        	// your network operation
    		InputStream is = null;
    		ArrayList<ContentValues> list = new ArrayList<ContentValues>();
    		ArrayList<NameValuePair> queryResult = new ArrayList<NameValuePair>();
    		StringBuilder sb = null;
    		String result;
    		
    		//httpPost
    		try{
    			HttpClient httpclient = new DefaultHttpClient();
    			HttpPost httppost = new HttpPost(REMOTE_QUERY_SITE + "?username=" + username);
    			httppost.setEntity(new UrlEncodedFormEntity(queryResult));
    			HttpResponse response = httpclient.execute(httppost);
    			HttpEntity entity = response.getEntity();
    			is = entity.getContent();
    		}catch(Exception e){
    			Log.e(this.toString(), "Error in http connection"+e.toString());
    			return new ArrayList<ContentValues>(0);
    		}
    		//convertString
    		try{
    			BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
    			sb = new StringBuilder();
    			sb.append(reader.readLine() + "\n");
    			String line="0";
    			while ((line = reader.readLine()) != null) {
    				sb.append(line + "\n");
    			}
    			is.close();
    			result=sb.toString();
    		}catch(Exception e){
    			Log.e("log_tag", "Error converting result "+e.toString());
    			return new ArrayList<ContentValues>(0);
    		}
    		//parseJSON
    		try
    		{
    			JSONArray jArray = new JSONArray(result);
    			JSONObject json_data=null;
    			for (int i = 0; i < jArray.length(); i++)
    			{
    				json_data = jArray.getJSONObject(i);
    				ContentValues cv = new ContentValues();
    				cv.put(TRIPS_TRIPID, json_data.getString(TRIPS_TRIPID));
    				cv.put(TRIPS_PROPID, json_data.getString(TRIPS_PROPID));
    				cv.put(TRIPS_PROPNAME, json_data.getString(TRIPS_PROPNAME));
    				cv.put(TRIPS_DATES, json_data.getString(TRIPS_DATES));
    				cv.put(TRIPS_AIRPORTS, json_data.getString(TRIPS_AIRPORTS));
    				cv.put(TRIPS_NOTES, json_data.getString(TRIPS_NOTES));
    				cv.put(TRIPS_FEATURES, json_data.getString(TRIPS_FEATURES));
    				list.add(cv);
    			}
    		}
    		catch(Exception e)
    		{
    			Log.e(this.toString(), "FAILURE TO ACQUIRE REMOTE PROP INFO");
    			e.printStackTrace();
    			return new ArrayList<ContentValues>(0);
    		}
            return list;
        }
    }
	
	private class RowAdapter extends ArrayAdapter<ContentValues>
	{
		private ArrayList<ContentValues> list;
		
		public RowAdapter(Context context, int textViewResourceId, ArrayList<ContentValues> noteList) 
        {
                super(context, textViewResourceId, noteList);
                list = noteList;
        }
		
		@Override
        public View getView(int position, View convertView, ViewGroup parent) 
        {
			View v = convertView;
        	if (v == null) 
        	{
        		LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        		v = vi.inflate(R.layout.selectproperty_item, parent, false);
        	}
        	
        	ContentValues cv = list.get(position);

        	TextView propName = (TextView) v.findViewById(R.id.trip_property);
        	TextView dates = (TextView) v.findViewById(R.id.trip_dates);
        	//TextView airports = (TextView) v.findViewById(R.id.trip_airports);
        	//TextView notes = (TextView) v.findViewById(R.id.trip_notes);
        	//TextView features = (TextView) v.findViewById(R.id.trip_features);
        	
        	propName.setText(cv.getAsString(TRIPS_PROPNAME));
        	dates.setText(cv.getAsString(TRIPS_DATES));
        	//airports.setText(cv.getAsString(TRIPS_AIRPORTS));
    		//notes.setText(cv.getAsString(TRIPS_NOTES));
    		//features.setText(cv.getAsString(TRIPS_FEATURES));
        	
        	return v;
        }
		
		@Override
		public int getCount()
		{
			if (trips != null)
			{
				return trips.size();
			}
			return 0;
		}
	}
}
