/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hmsoft.bluetooth.le;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import com.example.bluetooth.le.R;

import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;


/**
 * For a given BLE device, this Activity provides the user interface to connect, display data,
 * and display GATT services and characteristics supported by the device.  The Activity
 * communicates with {@code BluetoothLeService}, which in turn interacts with the
 * Bluetooth LE API.
 */
public class DeviceControlActivity extends Activity {
	private final static String TAG = DeviceControlActivity.class.getSimpleName();

	public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
	public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";

	private TextView mDataField;
	private String mDeviceName;
	private String mDeviceAddress;
	private BluetoothLeService mBluetoothLeService;
	private boolean mConnected = false;
	
	private String message = "";

	EditText edtSend;
	ScrollView svResult;
	Button btnSend;

	// Code to manage Service lifecycle.
	private final ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName componentName, IBinder service) {
			mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
			if (!mBluetoothLeService.initialize()) {
				Log.e(TAG, "Unable to initialize Bluetooth");
				finish();
			}

			Log.e(TAG, "mBluetoothLeService is okay");
			// Automatically connects to the device upon successful start-up initialization.
			//mBluetoothLeService.connect(mDeviceAddress);
		}

		@Override
		public void onServiceDisconnected(ComponentName componentName) {
			mBluetoothLeService = null;
		}
	};

	// Handles various events fired by the Service.
	// ACTION_GATT_CONNECTED: connected to a GATT server.
	// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
	// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
	// ACTION_DATA_AVAILABLE: received data from the device.  This can be a result of read
	//                        or notification operations.
	private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			
			if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {  //Á¬½Ó³É¹¦
				Log.e(TAG, "Only gatt, just wait");
			} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { //¶Ï¿ªÁ¬½Ó
				mConnected = false;
				invalidateOptionsMenu();
				btnSend.setEnabled(false);
				clearUI();
			}else if(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) //¿ÉÒÔ¿ªÊ¼¸É»îÁË
			{
				mConnected = true;
				mDataField.setText("");
				ShowDialog();
				btnSend.setEnabled(true);
				Log.e(TAG, "In what we need");
				invalidateOptionsMenu();
			}else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //ÊÕµ½Êý¾Ý
				Log.e(TAG, "RECV DATA");
				final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
				if (data != null) {
					if (mDataField.length() > 500)
						mDataField.setText("");
					mDataField.append("Calling messagebuilder:"+data+"\n");

					String mes = messageBuilder(data);
					mDataField.append("message to be sent: "+mes);
					if(mes!=null)
						new dweetClass().execute(mes);
					
					svResult.post(new Runnable() {
						public void run() {
							svResult.fullScroll(ScrollView.FOCUS_DOWN);
						}
					});
				}
			}
		}
	};

	private void clearUI() {
		mDataField.setText(R.string.no_data);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {                                        //³õÊ¼»¯
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gatt_services_characteristics);

		final Intent intent = getIntent();
		mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
		mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);

		// Sets up UI references.
		mDataField = (TextView) findViewById(R.id.data_value);
		edtSend = (EditText) this.findViewById(R.id.edtSend);
		edtSend.setText("www.jnhuamao.cn");
		svResult = (ScrollView) this.findViewById(R.id.svResult);

		btnSend = (Button) this.findViewById(R.id.btnSend);
		btnSend.setOnClickListener(new ClickEvent());
		btnSend.setEnabled(false);

		getActionBar().setTitle(mDeviceName);
		getActionBar().setDisplayHomeAsUpEnabled(true);
		Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
		Log.d(TAG, "Try to bindService=" + bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE));

		registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
	}
	
	private String messageBuilder(String data) {
		char delimiter = 'n';
		
		int msgbreak = data.indexOf(delimiter);
		
		if(msgbreak==-1) {
			message = message+data;
			return null;
		}
		else {
			String retval = message+data.substring(0,msgbreak);
			message = data.substring(msgbreak+1, data.length());
			return retval;
		}
	}
 
	@Override
	protected void onResume() {
		super.onResume();
		/*registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        if (mBluetoothLeService != null) {
            final boolean result = mBluetoothLeService.connect(mDeviceAddress);
            Log.d(TAG, "Connect request result=" + result);
        }*/
	}

	@Override
	protected void onPause() {
		super.onPause();
		unregisterReceiver(mGattUpdateReceiver);
		unbindService(mServiceConnection);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		//this.unregisterReceiver(mGattUpdateReceiver);
		//unbindService(mServiceConnection);
		if(mBluetoothLeService != null)
		{
			mBluetoothLeService.close();
			mBluetoothLeService = null;
		}
		Log.d(TAG, "We are in destroy");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.gatt_services, menu);
		if (mConnected) {
			menu.findItem(R.id.menu_connect).setVisible(false);
			menu.findItem(R.id.menu_disconnect).setVisible(true);
		} else {
			menu.findItem(R.id.menu_connect).setVisible(true);
			menu.findItem(R.id.menu_disconnect).setVisible(false);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {                              //µã»÷°´Å¥
		switch(item.getItemId()) {
		case R.id.menu_connect:
			mBluetoothLeService.connect(mDeviceAddress);
			return true;
		case R.id.menu_disconnect:
			mBluetoothLeService.disconnect();
			return true;
		case android.R.id.home:
			if(mConnected)
			{
				mBluetoothLeService.disconnect();
				mConnected = false;
			}
			onBackPressed();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	private void ShowDialog()
	{
		Toast.makeText(this, "This used to be a toast message. - Á¬½Ó³É¹¦£¬ÏÖÔÚ¿ÉÒÔÕý³£Í¨ÐÅ£¡", Toast.LENGTH_SHORT).show();
	}

	// °´Å¥ÊÂ¼þ
	class ClickEvent implements View.OnClickListener {
		@Override
		public void onClick(View v) {
			if (v == btnSend) {
				if(!mConnected) return;

				if (edtSend.length() < 1) {
					Toast.makeText(DeviceControlActivity.this, "ÇëÊäÈëÒª·¢ËÍµÄÄÚÈÝ", Toast.LENGTH_SHORT).show();
					return;
				}
				mBluetoothLeService.WriteValue(edtSend.getText().toString());

				InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
				if(imm.isActive())
					imm.hideSoftInputFromWindow(edtSend.getWindowToken(), 0);
				//todo Send data
			}
		}

	}

	private static IntentFilter makeGattUpdateIntentFilter() {                        //×¢²á½ÓÊÕµÄÊÂ¼þ
		final IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
		intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
		intentFilter.addAction(BluetoothDevice.ACTION_UUID);
		return intentFilter;
	}
}

class dweetClass extends AsyncTask<String, Void, HttpResponse> {

    private Exception exception;

    protected HttpResponse doInBackground(String... data) {
		//Dweet it here
		HttpClient client = new DefaultHttpClient();
		HttpGet request = new HttpGet("https://dweet.io/dweet/for/hrishiopo?"+data[0]);
		
		HttpResponse response = null;
		try {
			response = client.execute(request);
			
			Log.d("Response of GET request", response.toString());
		} catch(ClientProtocolException e) {
			e.printStackTrace();
		} catch(IOException e) {
			e.printStackTrace();
		}
		return response;
    }

    protected void onPostExecute(HttpResponse response) {
        // TODO: check this.exception 
        // TODO: do something with the feed
    }
}
