package com.example.facedemo;

import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.http.message.BasicNameValuePair;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.xuxin.mychat.FileUploadUtil;
import com.xuxin.mychat.HttpDownloader;
import com.xuxin.mychat.mina.ChatClientHandler;
import com.xuxin.mychat.mina.ChatClientHandler.Callback;
import com.xuxin.mychat.mina.ChatClientSupport;
import com.xuxin.mychat.model.MyMessage;

public class ChatActivity extends Activity implements Callback, OnClickListener {

	private ListView mListView;

	private ChatMsgAdapter mAdapter;

	private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();

	// 参数信息
	private String userInfo, connectInfo;
	private ChatClientHandler handler;
	private ChatClientSupport client;
	private SocketAddress address;
	private String httpUrl;

	private final String uploadUrl = "/aisin/chat/fileUpload.ctl";
	private final String downLoadurl = "/aisin/chat/fileDownLoad.ctl";

	private Gson gson = new Gson();
	// 录音
	private Button mBtnSend;
	private ImageView ivPopUp_btn, volume;
	private ImageButton btn_face;
	private EditText mEditTextContent;

	private TextView mBtnRcd;// voice btn

	private boolean btn_vocie = false;
	// private RelativeLayout textRelativeLayout;
	// private RelativeLayout voiceRelativeLayout;
	private View rcChat_popup;
	private LinearLayout voice_rcd_hint_loading, voice_rcd_hint_rcding,
			voice_rcd_hint_tooshort;
	private ImageView img1, sc_img1;

	private LinearLayout del_re;
	private int flag = 1;
	private boolean isShosrt = false;
	private long startVoiceT, endVoiceT;
	private String voiceName;
	private SoundMeter mSensor;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_chat);
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

		Bundle bundle = this.getIntent().getExtras();
		userInfo = bundle.get("userInfo").toString();
		connectInfo = bundle.get("connectInfo").toString();
		httpUrl = bundle.get("httpUrl").toString();

		handler = new ChatClientHandler(ChatActivity.this);
		client = new ChatClientSupport(userInfo, handler);
		address = parseSocketAddress(connectInfo);

		initView();
		initData();

		chatBroadcast("[#system#][" + userInfo + "] 加入了聊天");
	}

	public void initView() {
		mListView = (ListView) findViewById(R.id.listview);
		mBtnSend = (Button) findViewById(R.id.btn_send);
		mBtnSend.setOnClickListener(this);

		mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);
		ivPopUp_btn = (ImageView) this.findViewById(R.id.ivPopUp);
		btn_face = (ImageButton) this.findViewById(R.id.btn_face);
		mBtnRcd = (TextView) findViewById(R.id.btn_rcd);
		del_re = (LinearLayout) this.findViewById(R.id.del_re);
		rcChat_popup = this.findViewById(R.id.rcChat_popup);
		voice_rcd_hint_rcding = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_rcding);
		voice_rcd_hint_loading = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_loading);
		voice_rcd_hint_tooshort = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_tooshort);
		img1 = (ImageView) this.findViewById(R.id.img1);
		sc_img1 = (ImageView) this.findViewById(R.id.sc_img1);
		volume = (ImageView) this.findViewById(R.id.volume);
		mSensor = new SoundMeter();

		// 语音文字切换按钮
		ivPopUp_btn.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {

				if (btn_vocie) {
					btn_face.setVisibility(View.VISIBLE);
					mEditTextContent.setVisibility(View.VISIBLE);
					mBtnSend.setVisibility(View.VISIBLE);

					mBtnRcd.setVisibility(View.GONE);

					ivPopUp_btn
							.setImageResource(R.drawable.chatting_setmode_msg_btn);
					btn_vocie = false;
				} else {
					btn_face.setVisibility(View.GONE);
					mEditTextContent.setVisibility(View.GONE);
					mBtnSend.setVisibility(View.GONE);
					mBtnRcd.setVisibility(View.VISIBLE);
					ivPopUp_btn
							.setImageResource(R.drawable.chatting_setmode_voice_btn);
					btn_vocie = true;
				}

			}
		});

		mBtnRcd.setOnTouchListener(new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				// 按下语音录制按钮时返回false执行父类OnTouch
				return false;
			}
		});
	}

	public void initData() {
		mAdapter = new ChatMsgAdapter(this, mDataArrays);
		mListView.setAdapter(mAdapter);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_send:
			send();
			break;
		}
	}

	private void back() {// 下线
		client.logout();
		finish();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK
				&& ((FaceRelativeLayout) findViewById(R.id.FaceRelativeLayout))
						.hideFaceView()) {
			return true;
		}
		// back();
		return super.onKeyDown(keyCode, event);
	}

	private void send() {
		final String contString = mEditTextContent.getText().toString();
		if (contString.length() > 0) {
			mEditTextContent.setText("");
			chatBroadcast(contString);
			// 进行mina发送
			// new Thread() {
			// @Override
			// public void run() {
			// try {
			// client.broadcast(address, contString);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
			// }
			// }.start();

		}
	}

	private void chatBroadcast(final String msg) {
		if (msg.length() > 0) {
			new Thread() {
				@Override
				public void run() {
					try {
						client.broadcast(address, msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}.start();

		}
	}

	@SuppressLint("HandlerLeak")
	Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			ChatMsgEntity entity = (ChatMsgEntity) msg.obj;
			mDataArrays.add(entity);
			mAdapter.notifyDataSetChanged();
			mListView.setSelection(mListView.getCount() - 1);
		}

	};

	@Override
	public void messageReceived(String message) {
		String json = message.toString();
		Log.i("messageReceived", json);

		final MyMessage msg = gson.fromJson(json, MyMessage.class);
		final String fromMessage = msg.getMessage();

		ChatMsgEntity entity = new ChatMsgEntity();

		entity.setDate(getDate());
		entity.setName(msg.getUsername());
		entity.setText(msg.getMessage());

		if (msg.getUsername().equals(userInfo)) {// the message is from self
			if (!fromMessage.contains(".amr")) {
				entity.setMsgType(false);

				Message msg1 = new Message();
				msg1.obj = entity;
				mHandler.sendMessage(msg1);
			}

		} else {// the message is from others
			if (fromMessage.contains(".amr")) {// judge text or voice
				// download the voice
				new Thread() {
					@Override
					public void run() {
						try {
							HttpDownloader httpDownloader = new HttpDownloader();
							if (fromMessage.contains("_")
									&& fromMessage.split("_").length == 2) {
								String formUserInfo = fromMessage.split("_")[0];
								String fileName = fromMessage.split("_")[1];

								List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
								params.add(new BasicNameValuePair("userInfo",
										formUserInfo));
								params.add(new BasicNameValuePair("fileName",
										fileName));

								// String param = "userInfo=" + formUserInfo
								// + "&fileName=" + fileName;
								//
								// int downLoadflag =
								// httpDownloader.downFile(httpUrl
								// + downLoadurl, param, "/", fromMessage);

								int downLoadflag = httpDownloader
										.httpClientDown(httpUrl + downLoadurl,
												params, fromMessage);

								Log.i("download flag = ", downLoadflag + "");

								if (0 == downLoadflag) {
									ChatMsgEntity voiceEntity = new ChatMsgEntity();
									voiceEntity.setMsgType(true);
									voiceEntity.setDate(getDate());
									voiceEntity.setName(msg.getUsername());
									voiceEntity.setText(fromMessage);

									Message msg1 = new Message();
									msg1.obj = voiceEntity;
									mHandler.sendMessage(msg1);
								}

							}

						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}.start();

			} else {// normal text
				entity.setMsgType(true);

				Message msg1 = new Message();
				msg1.obj = entity;
				mHandler.sendMessage(msg1);
			}

		}

	}

	private String getDate() {
		Calendar c = Calendar.getInstance();

		String year = String.valueOf(c.get(Calendar.YEAR));
		String month = String.valueOf(c.get(Calendar.MONTH));
		String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);
		String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
		String mins = String.valueOf(c.get(Calendar.MINUTE));

		StringBuffer sbBuffer = new StringBuffer();
		sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":"
				+ mins);

		return sbBuffer.toString();
	}

	@Override
	public void connected(boolean flag) {
		// TODO Auto-generated method stub

	}

	@Override
	public void loggedIn() {
		// TODO Auto-generated method stub

	}

	@Override
	public void loggedOut() {
		// TODO Auto-generated method stub

	}

	@Override
	public void error(String message) {
		// TODO Auto-generated method stub

	}

	private SocketAddress parseSocketAddress(String s) {
		s = s.trim();
		int colonIndex = s.indexOf(":");
		if (colonIndex > 0) {
			String host = s.substring(0, colonIndex);
			int port = parsePort(s.substring(colonIndex + 1));
			return new InetSocketAddress(host, port);
		} else {
			int port = parsePort(s.substring(colonIndex + 1));
			return new InetSocketAddress(port);
		}
	}

	private int parsePort(String s) {
		try {
			return Integer.parseInt(s);
		} catch (NumberFormatException nfe) {
			throw new IllegalArgumentException("Illegal port number: " + s);
		}
	}

	// 按下语音录制按钮时
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		if (!Environment.getExternalStorageDirectory().exists()) {
			Toast.makeText(this, "No SDCard", Toast.LENGTH_LONG).show();
			return false;
		}

		File localDir = new File(Environment.getExternalStorageDirectory()
				+ "/zzzz/");
		if (!localDir.exists()) {
			if (!localDir.mkdir()) {
				Toast.makeText(this, "Create SDCard Dir Fail",
						Toast.LENGTH_LONG).show();
				return false;
			}

		}

		if (btn_vocie) {
			System.out.println("1");
			int[] location = new int[2];
			mBtnRcd.getLocationInWindow(location); // 获取在当前窗口内的绝对坐标
			int btn_rc_Y = location[1];
			int btn_rc_X = location[0];
			int[] del_location = new int[2];
			del_re.getLocationInWindow(del_location);
			int del_Y = del_location[1];
			int del_x = del_location[0];
			if (event.getAction() == MotionEvent.ACTION_DOWN && flag == 1) {
				if (!Environment.getExternalStorageDirectory().exists()) {
					Toast.makeText(this, "No SDCard", Toast.LENGTH_LONG).show();
					return false;
				}
				System.out.println("2");
				if (event.getY() > btn_rc_Y && event.getX() > btn_rc_X) {// 判断手势按下的位置是否是语音录制按钮的范围内
					System.out.println("3");
					mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_pressed);
					rcChat_popup.setVisibility(View.VISIBLE);
					voice_rcd_hint_loading.setVisibility(View.VISIBLE);
					voice_rcd_hint_rcding.setVisibility(View.GONE);
					voice_rcd_hint_tooshort.setVisibility(View.GONE);
					mHandler.postDelayed(new Runnable() {
						public void run() {
							if (!isShosrt) {
								voice_rcd_hint_loading.setVisibility(View.GONE);
								voice_rcd_hint_rcding
										.setVisibility(View.VISIBLE);
							}
						}
					}, 300);
					img1.setVisibility(View.VISIBLE);
					del_re.setVisibility(View.GONE);

					// startVoiceT = SystemClock.currentThreadTimeMillis();
					startVoiceT = getUUID();

					voiceName = startVoiceT + ".amr";
					start(voiceName);
					flag = 2;
				}
			} else if (event.getAction() == MotionEvent.ACTION_UP && flag == 2) {// 松开手势时执行录制完成
				System.out.println("4");
				mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_nor);
				if (event.getY() >= del_Y
						&& event.getY() <= del_Y + del_re.getHeight()
						&& event.getX() >= del_x
						&& event.getX() <= del_x + del_re.getWidth()) {
					rcChat_popup.setVisibility(View.GONE);
					img1.setVisibility(View.VISIBLE);
					del_re.setVisibility(View.GONE);
					stop();
					flag = 1;
					File file = new File(
							android.os.Environment
									.getExternalStorageDirectory()
									+ "/zzzz/"
									+ voiceName);
					if (file.exists()) {
						file.delete();
					}
				} else {
					voice_rcd_hint_rcding.setVisibility(View.GONE);
					stop();
					endVoiceT = SystemClock.currentThreadTimeMillis();
					flag = 1;

					System.out.println("毫秒时差" + (endVoiceT - startVoiceT));

					int time = (int) ((endVoiceT - startVoiceT) / 30);
					if (time < 1) {
						isShosrt = true;
						voice_rcd_hint_loading.setVisibility(View.GONE);
						voice_rcd_hint_rcding.setVisibility(View.GONE);
						voice_rcd_hint_tooshort.setVisibility(View.VISIBLE);
						mHandler.postDelayed(new Runnable() {
							public void run() {
								voice_rcd_hint_tooshort
										.setVisibility(View.GONE);
								rcChat_popup.setVisibility(View.GONE);
								isShosrt = false;
							}
						}, 500);
						return false;
					}

					rcChat_popup.setVisibility(View.GONE);

					File file = new File(
							android.os.Environment
									.getExternalStorageDirectory()
									+ "/zzzz/"
									+ voiceName);
					if (file.exists()) {// this will upload voice file
						Log.i("local file path", file.getPath());

						// send voice
						ChatMsgEntity entity = new ChatMsgEntity();
						entity.setDate(getDate());
						entity.setName(userInfo);
						entity.setMsgType(false);
						entity.setTime(time + "\"");
						entity.setText(voiceName);

						Message msg1 = new Message();
						msg1.obj = entity;
						mHandler.sendMessage(msg1);

						final Map<String, File> upfiles = new HashMap<String, File>();
						upfiles.put("file", file);

						// send voice
						new Thread() {
							@Override
							public void run() {
								try {
									Map<String, String> params = new HashMap<String, String>();
									params.put("userInfo", userInfo);
									params.put("fileName", voiceName);
									boolean flag = FileUploadUtil.uploadFile(
											httpUrl + uploadUrl, params,
											upfiles);

									if (flag) {
										// client.broadcast(address, userInfo
										// + "_" + voiceName);
										chatBroadcast(userInfo + "_"
												+ voiceName);
									} else {
										Toast.makeText(getApplicationContext(),
												"上传文件失败", Toast.LENGTH_LONG)
												.show();
									}
								} catch (Exception e) {
									e.printStackTrace();
								} finally {

								}
							}
						}.start();

					} else {
						System.out.println("file is not exist");
					}

				}
			}
			if (event.getY() < btn_rc_Y) {// 手势按下的位置不在语音录制按钮的范围内
				System.out.println("5");
				Animation mLitteAnimation = AnimationUtils.loadAnimation(this,
						R.anim.cancel_rc);
				Animation mBigAnimation = AnimationUtils.loadAnimation(this,
						R.anim.cancel_rc2);
				img1.setVisibility(View.GONE);
				del_re.setVisibility(View.VISIBLE);
				del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg);
				if (event.getY() >= del_Y
						&& event.getY() <= del_Y + del_re.getHeight()
						&& event.getX() >= del_x
						&& event.getX() <= del_x + del_re.getWidth()) {
					del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg_focused);
					sc_img1.startAnimation(mLitteAnimation);
					sc_img1.startAnimation(mBigAnimation);
				}
			} else {

				img1.setVisibility(View.VISIBLE);
				del_re.setVisibility(View.GONE);
				del_re.setBackgroundResource(0);
			}
		}
		return super.onTouchEvent(event);
	}

	private static final int POLL_INTERVAL = 300;

	private Runnable mSleepTask = new Runnable() {
		public void run() {
			stop();
		}
	};
	private Runnable mPollTask = new Runnable() {
		public void run() {
			double amp = mSensor.getAmplitude();
			updateDisplay(amp);
			mHandler.postDelayed(mPollTask, POLL_INTERVAL);

		}
	};

	private void start(String name) {
		mSensor.start(name);
		mHandler.postDelayed(mPollTask, POLL_INTERVAL);
	}

	private void stop() {
		mHandler.removeCallbacks(mSleepTask);
		mHandler.removeCallbacks(mPollTask);
		mSensor.stop();
		volume.setImageResource(R.drawable.amp1);
	}

	private void updateDisplay(double signalEMA) {

		switch ((int) signalEMA) {
		case 0:
		case 1:
			volume.setImageResource(R.drawable.amp1);
			break;
		case 2:
		case 3:
			volume.setImageResource(R.drawable.amp2);

			break;
		case 4:
		case 5:
			volume.setImageResource(R.drawable.amp3);
			break;
		case 6:
		case 7:
			volume.setImageResource(R.drawable.amp4);
			break;
		case 8:
		case 9:
			volume.setImageResource(R.drawable.amp5);
			break;
		case 10:
		case 11:
			volume.setImageResource(R.drawable.amp6);
			break;
		default:
			volume.setImageResource(R.drawable.amp7);
			break;
		}
	}

	private long getUUID() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("MMddHHmmssssss");
		Long uuid = new Long(formatter.format(currentTime));
		return uuid;
	}
}