package com.ethostream.ethoandroid;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
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.View;
import android.widget.Button;
import android.widget.TextView;

public class EthoAndroid extends Activity
{
//    private LocalSQLiteHelper dbParent;
    private DatabaseLoginAdapter mDbHelper;
    
    private static final int ACTIVITY_SELECTPROPERTY = 0;
	private static final String REMOTE_LOGIN_SITE = "http://android.telkonet.com/dblogin.php";
	private static final String REMOTE_USERNAME = "Username";
	private static final String REMOTE_PASSWORD = "Password";

	private static final int LOGIN_INCORRECT = 0;
	
	private ContentValues cv = new ContentValues(0);
    private String username = "";
    private String password = "";
    private String hashword = "";
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        context = this;
        mDbHelper = new DatabaseLoginAdapter(this);
        mDbHelper.open();
        setContentView(R.layout.main);
        final TextView usernameField = (TextView) findViewById(R.id.login_username);
        final TextView passwordField = (TextView) findViewById(R.id.login_password);
        
        if (savedInstanceState != null && savedInstanceState.containsKey("LOGOUT"))
        {
        	mDbHelper.dropLoginTable();
        	mDbHelper.createLoginTable();
        }

        
        // First see if there is an existing login in the database
        Cursor logins = mDbHelper.getAll();
        if (logins.getCount() > 0)
        {
        	Log.i(this.toString(), "Getting info from DB");
        	// There is something in the database, see if it is a valid login
        	logins.moveToFirst();
        	username = logins.getString(1);
        	password = logins.getString(2);
        	usernameField.setText(username);
        	passwordField.setText(password);
        	logins.close();
        	LoginThread lt = new LoginThread();
        	lt.execute(new String[]{username, password});
        	boolean result = false;
			try
			{
				//TODO timeout and messages
				result = lt.get().booleanValue();
			} catch (InterruptedException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	if (result)
        	{
        		// switch view
        		switchView(ACTIVITY_SELECTPROPERTY, "USERNAME", username);
        	}
        	else
        	{
        		// show dialog
        		showDialog(LOGIN_INCORRECT);
        	}
        }
        Log.i(this.toString(), "Nothing in DB");
        // If there is nothing valid in the database, wait for input     
        Button loginButton = (Button) findViewById(R.id.login_button);
        Log.i(this.toString(), findViewById(R.id.login_button).toString());
        Log.i(this.toString(), loginButton.toString());
        loginButton.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View view) 
            {
            	username = usernameField.getText().toString();
            	password = passwordField.getText().toString();
            	MessageDigest md5;
				try
				{
					md5 = MessageDigest.getInstance("MD5");
				} catch (NoSuchAlgorithmException e)
				{
					Log.e(this.toString(), "Encryption algorithm error. Exiting.");
					e.printStackTrace();
					return;
				}
            	md5.update(password.getBytes());
            	BigInteger hash = new BigInteger(1, md5.digest());
            	hashword = hash.toString(16);
            	StringBuffer buffer = new StringBuffer(hashword);
            	while (buffer.length() < 32) 
            	{
            		buffer.insert(0, '0');
            	}
            	hashword = buffer.toString();
            	mDbHelper.dropLoginTable();
            	mDbHelper.createLoginTable();
            	cv.clear();
            	cv.put(REMOTE_USERNAME, username);
            	cv.put(REMOTE_PASSWORD, hashword);
            	mDbHelper.createLogin(cv);
            	LoginThread lt = new LoginThread();
            	lt.execute(new String[]{username, hashword});
            	boolean result = false;
				try
				{
					//TODO timeout and messages
					result = lt.get().booleanValue();
				} catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ExecutionException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            	if (result)
            	{
            		// switch view
            		switchView(ACTIVITY_SELECTPROPERTY, "USERNAME", username);
            	}
            	else
            	{
            		// show dialog
            		showDialog(LOGIN_INCORRECT);
            	}
            }
        });

    }
    
	private class LoginThread extends AsyncTask<String, Void, Boolean> 
	{
		final ProgressDialog dialog = new ProgressDialog(context);
		@Override
		protected void onPreExecute()
		{
			dialog.setTitle(R.string.login_progress_label);
			dialog.setMessage(context.getString(R.string.login_progress_message));
			dialog.show();
		}
		@Override
		protected Boolean doInBackground(String... params) 
		{
			if (login(params[0],params[1]))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		@Override
		protected void onPostExecute(Boolean retValue) 
		{
			dialog.dismiss();
		}
	 }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        super.onActivityResult(requestCode, resultCode, intent);
        Bundle bundle = intent.getExtras();
        onCreate(bundle);
    }
    
    private void switchView(int ACTIVITY, String key, String value)
    {
    	switch(ACTIVITY)
    	{
    		case ACTIVITY_SELECTPROPERTY:
    		{
            	Intent i = new Intent(this, SelectProperty.class);
            	i.putExtra(key, value);
            	startActivityForResult(i, ACTIVITY_SELECTPROPERTY);
            	break;
    		}
    		default:
    		{
    			break;
    		}
    	}
    }
    
    protected Dialog onCreateDialog(int id) 
    {
    	Dialog dialog;
    	AlertDialog.Builder builder;
    	AlertDialog alert;
    	switch(id) 
    	{
    		case LOGIN_INCORRECT:
    			builder = new AlertDialog.Builder(this);
    			builder.setMessage(this.getString(R.string.dialog_login_incorrect))
    			.setCancelable(false)
    			.setPositiveButton(this.getString(R.string.dialog_login_incorrect_yes), new DialogInterface.OnClickListener() 
    				{
    				public void onClick(DialogInterface dialog, int id) 
    				{
    					//Do something
    				}
    			});
    			alert = builder.create();
    			dialog = alert;
    			break;
    		default:
    			dialog = null;
    	}
    	return dialog;
    }
    
    private boolean login(String username, String password)
    {
    	cv = remoteLogin(username, password);
    	if (cv.size() != 2)
    	{
    		Log.e(this.toString(), "Incorrect Username/Password");
    		return false;
    	}
    	mDbHelper.close();
    	return true;
    }
    
    private ContentValues remoteLogin(String username, String password)
    {
    	ContentValues cv = new ContentValues();
    	InputStream is = null;
		ArrayList<NameValuePair> queryResult = new ArrayList<NameValuePair>();
		StringBuilder sb = null;
		String result;
		
		//httpPost
		try{
			HttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(REMOTE_LOGIN_SITE + "?username=" + username + "&password=" + password);
			//Log.e(this.toString(), ""+REMOTE_LOGIN_SITE + "?username=" + username + "&password=" + password);
			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 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 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);				
				cv.put(REMOTE_USERNAME, json_data.getString(REMOTE_USERNAME));
				cv.put(REMOTE_PASSWORD, json_data.getString(REMOTE_PASSWORD));
			}
		}
		catch(Exception e)
		{
			Log.e(this.toString(), "Incorrect Username/Password");
			return new ContentValues(0);
		}
		return cv;
    }
}
