package jp.agentec.abook.abv.ui.home.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Html;
import android.text.InputType;
import android.text.format.DateUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

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

import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.exception.HttpUnauthorizedException;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.exception.ServerException;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.MeetingDto;
import jp.agentec.abook.abv.bl.websocket.MeetingManager;
import jp.agentec.abook.abv.cl.util.AndroidStringUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.UserPrefKey;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.adf.util.StringUtil;

import static jp.agentec.abook.abv.cl.util.PreferenceUtil.getUserPref;

public class OperationMeetingListActivity extends ABVUIActivity {
	private static final String TAG = "OperationMeetingListActivity";
	private String mSkey;
	private List<MeetingDto> mMeetingDtoList;
	private MeetingManager mMeetingManager;
	private ActivityHandlingHelper mActivityHandlingHelper;

	private LinearLayout mMeetingAddLayout;
	private EditText mMeetingRoomNameTxt;
	private EditText mMeetingRoomPasswordTxt;

	private LinearLayout mMeetingListLayout;
	private Button mCloseBtn;
	private Button mAddBtn;
	private Button mLeaveBtn;
	private LayoutInflater mInflater;
	private PullToRefreshListView mListView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Logger.i(TAG, "onCreate");
		super.onCreate(savedInstanceState);
		mActivityHandlingHelper = ActivityHandlingHelper.getInstance();
		
		mMeetingManager = MeetingManager.getInstance();
		mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);


		if (mInflater != null) {
			mMeetingListLayout = (LinearLayout) mInflater.inflate(R.layout.ac_operation_meeting_list, null);
		}
		mListView = (PullToRefreshListView) mMeetingListLayout.findViewById(R.id.meeting_list_listView); // 一覧
		mListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
			@Override
			public void onRefresh(PullToRefreshBase<ListView> refreshView) {
				String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
						DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
				// Update the LastUpdatedLabel
				refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
				CommonExecutor.execute(new Runnable() {
					@Override
					public void run() {
						handler.post(new Runnable() {
							@Override
							public void run() {
								reloadMeetingList();
								mListView.onRefreshComplete();
							}
						});
						
					}
				});

			}
		});
		// 会議室一覧画面
		createMeetingListView();

		mActivityHandlingHelper.unloadOperationMeetingListActivity();
		mActivityHandlingHelper.setOperationMeetingListActivity(this);
	}

	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		Logger.v(TAG, "dispatchKeyEvent %s", event);
		if (mMeetingManager.isSubscribed()) {
			if (event.getAction()==KeyEvent.ACTION_UP) { // 戻るボタンを抑止
				switch (event.getKeyCode()) {
					case KeyEvent.KEYCODE_BACK:
						return true;
				}
			}
		}
		return super.dispatchKeyEvent(event);
	}

	@Override
	protected void onDestroy() {
		mActivityHandlingHelper.setOperationMeetingListActivity(null);
		super.onDestroy();
	}

	/**
	 * 会議室一覧画面
	 * 
	 */
	private void createMeetingListView() {

		CommonExecutor.execute(new Runnable() { // syncviewサーバにアクセスしてリストを取得する（固まる可能性があるため別スレッドで）
			@Override
            public void run() {
				loadMeetingList(); // 一覧取得
				handler.post(new Runnable() {
					@Override
					public void run() {
						refreshListView();
					}
				});
			}
        });

		mCloseBtn = (Button) mMeetingListLayout.findViewById(R.id.close); // 閉じるボタン
		mCloseBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
                Logger.v(TAG, "mCloseBtn.onClick");
				finish();
				if (isNormalSize()) {
					overridePendingTransition(0, R.anim.view_down);
				}
			}
		});

		mAddBtn = (Button) mMeetingListLayout.findViewById(R.id.meeting_add); // 新規作成ボタン
		mAddBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "mAddBtn.onClick");
				// 会議室追加画面
				createMeetingAddView();
			}
		});

		mLeaveBtn = (Button) mMeetingListLayout.findViewById(R.id.meeting_leave); // 退室ボタン
		final boolean isEntered = mMeetingManager.isEntered(mMeetingDtoList) && mMeetingManager.isConnected();

		mLeaveBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.i(TAG, "leaveBtn onclick!!!");

				if (mMeetingManager.isConnected()) { // 入室している場合（退室ボタン）
					if (mMeetingManager.isOwner()) { // 司会者の場合
						ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(OperationMeetingListActivity.this, R.string.confirm);
						// リソースパターンの適用
						alert.setMessage(AndroidStringUtil.format(OperationMeetingListActivity.this,
								PatternStringUtil.patternToInt(getApplicationContext(),
										R.string.msg_confirm_exit_meeting_room,
										getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)),
								PatternStringUtil.patternToInt(getApplicationContext(),
										R.string.meeting_leave,
										getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
						alert.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								try {
									mMeetingManager.deleteMeeting(mMeetingManager.getJoinedMeetingDto().meetingId, mSkey); // 退室と同時に削除も行う
								} catch (ServerException e) {
									Logger.e(TAG, "deleteMeeting failed", e);
									showErrorMessage(e);
								} catch (Exception e) {
									Logger.e(TAG, "deleteMeeting failed", e);
									handleErrorMessageToast(getString(R.string.E126));
								}
								closeMeetingRoom();
								mActivityHandlingHelper.saveMeetingInfo(null, null, null, false);
//								reloadMeetingList();
								finish();
							}
						});
						alert.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								dialog.cancel();
							}
						});
						alert.show();
					}
				}

			}
		});

		TextView titleTxt = (TextView) mMeetingListLayout.findViewById(R.id.meeting_list_title);
		if (mMeetingManager.isConnected() && mMeetingManager.isOwner()) {
			// リソースパターンの適用
			titleTxt.setText(PatternStringUtil.patternToInt(getApplicationContext(),
								R.string.room_list,
								getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			mAddBtn.setVisibility(View.GONE);
			mLeaveBtn.setVisibility(View.VISIBLE);
		} else {
			// リソースパターンの適用
			titleTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
								R.string.remote_support_list,
								getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			mAddBtn.setVisibility(View.VISIBLE);
			mLeaveBtn.setVisibility(View.GONE);
		}
		
		setContentView(mMeetingListLayout);
	}

	/**
	 * listViewにAdapterをセットする
	 */
	protected void refreshListView() {
		mListView.setAdapter(new BaseAdapter() {
			// 必ず1件は入っている
			boolean isEmptyView = mMeetingDtoList.get(0).isEmptyView;

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					if (isEmptyView) {
						convertView = mInflater.inflate(android.R.layout.simple_list_item_1, null);
					} else {
						convertView = mInflater.inflate(R.layout.item_operation_meeting_list_render, parent, false);
					}
				}
				if (isEmptyView) {
					TextView tv = (TextView) convertView;
					if (mMeetingManager.isConnected() && mMeetingManager.isOwner()) {
						tv.setVisibility(View.GONE);
					} else {
						tv.setText(R.string.msg_no_data);
						tv.setBackgroundResource(R.drawable.rounded_edittext4search);
						tv.setGravity(Gravity.CENTER);
						tv.setTextColor(Color.GRAY);
						tv.setPadding(10, 50, 10, 50);
						tv.setTextSize(20);
					}
				} else {
					createMeetingList(position, convertView);
				}
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return (mMeetingDtoList == null) ? -1 : mMeetingDtoList.get(position).meetingId;
			}

			@Override
			public Object getItem(int position) {
				return (mMeetingDtoList == null) ? null : mMeetingDtoList.get(position);
			}

			@Override
			public int getCount() {
				return (mMeetingDtoList == null) ? 0 : mMeetingDtoList.size();
			}
		});
		configureViewVisibility();

		ProgressBar progressBar = (ProgressBar) mMeetingListLayout.findViewById(R.id.progressbar_small);
		TextView titleTxt = (TextView) mMeetingListLayout.findViewById(R.id.meeting_list_title);
		if (mMeetingManager.isSubscribed()) {
			progressBar.setVisibility(View.VISIBLE);
			titleTxt.setText(R.string.waiting);
		} else {
			progressBar.setVisibility(View.GONE);
			if (mAddBtn.getVisibility() == View.VISIBLE) {
				// リソースパターンの適用
				titleTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
									R.string.remote_support_list,
									getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
				// リソースパターンの適用
			} else {
				titleTxt.setText(PatternStringUtil.patternToInt(getApplicationContext(),
									R.string.room_list,
									getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			}
		}
	}

	/**
	 * 会議室一覧ビューの作成
	 * 
	 * @param position
	 * @param convertView
	 */
	private void createMeetingList(int position, final View convertView) {
		final MeetingDto meetingDto = mMeetingDtoList.get(position);
		Logger.i(TAG, "meetingDto " + meetingDto);

		final boolean isEntered = mMeetingManager.isEntered(mMeetingDtoList) && mMeetingManager.isConnected();

		if (meetingDto.isEmptyView) {
			convertView.setVisibility(View.INVISIBLE);
			return;
		}

		TextView meetingIdTxt = (TextView) convertView.findViewById(R.id.meeting_id);
		meetingIdTxt.setText(""+meetingDto.meetingId);

		TextView participantCountTxt = (TextView) convertView.findViewById(R.id.participant_count);
		participantCountTxt.setText(""+meetingDto.attendees);

		TextView meetingRoomNameTxt = (TextView) convertView.findViewById(R.id.meeting_room_name);
		meetingRoomNameTxt.setText(meetingDto.title);

		TextView createDateTxt = (TextView) convertView.findViewById(R.id.create_date);
//		String strCreateDate = DateTimeUtil.toString(DateTimeUtil.toDate(meetingDto.createdate, "UTC", DateTimeFormat.yyyyMMddHHmmss_hyphen), DateTimeFormat.yyyyMMdd_slash);
		createDateTxt.setText(meetingDto.getCreateDateInLocalTime());

		TextView creatorTxt = (TextView) convertView.findViewById(R.id.creator);
		creatorTxt.setText(meetingDto.ownerName);

		TextView passwordSetTxt = (TextView) convertView.findViewById(R.id.password_set);
		if (meetingDto.type == MeetingDto.TYPE_PASSWORD) {
			// リソースパターンの適用
			passwordSetTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
					R.string.exist,
					getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
		} else {
			// リソースパターンの適用
			passwordSetTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
					R.string.not_exist,
					getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
		}

		if (isNormalSize()) {
			int size = 12;
			meetingIdTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
			meetingRoomNameTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
			creatorTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
			createDateTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
			participantCountTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
		}
		
		Button enterLeaveBtn = (Button) convertView.findViewById(R.id.enter_leave); // 入室ボタン
		enterLeaveBtn.setOnClickListener(new OnClickListener() { // 入室・退室ボタンクリック
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "enterLeaveBtn onclick!!!");
				if (isEntered) { // 入室している場合（退室ボタン）
					if (mMeetingManager.isOwner()) { // 司会者の場合
						ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(OperationMeetingListActivity.this, R.string.confirm);
						alert.setMessage(AndroidStringUtil.format(OperationMeetingListActivity.this, R.string.msg_leave_all, R.string.meeting_leave));
						alert.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								try {
									mMeetingManager.deleteMeeting(meetingDto.meetingId, mSkey); // 退室と同時に削除も行う
								} catch (ServerException e) {
									Logger.e(TAG, "deleteMeeting failed", e);
									showErrorMessage(e);
								} catch (Exception e) {
									Logger.e(TAG, "deleteMeeting failed", e);
									handleErrorMessageToast(getString(R.string.E126));
								}
								closeMeetingRoom();
								mActivityHandlingHelper.saveMeetingInfo(null, null, null, false);
								reloadMeetingList();
							}
						});
						alert.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								dialog.cancel();
							}
						});
						alert.show();
					}
					else { // 参加者の場合
						ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(OperationMeetingListActivity.this, R.string.confirm);
						alert.setMessage(R.string.msg_leave);
						alert.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								closeMeetingRoom();
								mActivityHandlingHelper.saveMeetingInfo(null, null, null, false);
								reloadMeetingList();
							}
						});
						alert.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int whichButton) {
								dialog.cancel();
							}
						});
						alert.show();
					}
				}
				else { // 入室ボタン押下の場合
					if(meetingDto.appversion != null && meetingDto.appversion.equals(MeetingManager.MEETING_VERSION)){
						joinMeeting(meetingDto);
					} else {
						ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(OperationMeetingListActivity.this, getRString(R.string.meeting_room) , getRString(R.string.msg_different_meeting_version));
						alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								joinMeeting(meetingDto);
							}
						});
						alert.show();
					}
				}
			}
		});

		enterLeaveBtn.setVisibility(View.VISIBLE);
		if (isEntered) {
			enterLeaveBtn.setText(getString(R.string.meeting_leave));
			mAddBtn.setClickable(false);
			mAddBtn.setTextColor(this.getResources().getColor(R.color.basic_white2));
			mCloseBtn.setVisibility(View.INVISIBLE);

		}
		else {
			enterLeaveBtn.setText(getString(R.string.meeting_enter));
			mAddBtn.setClickable(true);
			mAddBtn.setTextColor(this.getResources().getColor(R.color.basic_white1));
			mCloseBtn.setVisibility(View.VISIBLE);
		}

		if (mMeetingManager.isConnected() && mMeetingManager.isOwner()) {
			enterLeaveBtn.setVisibility(View.GONE);
		}

	}

	private void joinMeeting(final MeetingDto meetingDto) {
		final boolean isOwner = mSkey.equals(meetingDto.presenterskey);
		if (meetingDto.type == MeetingDto.TYPE_PASSWORD) {
			// パスワード入力ダイアローグ
			final EditText passwordTxt = new EditText(OperationMeetingListActivity.this);
			passwordTxt.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
			ABookAlertDialog alert = AlertDialogUtil.createAlertDialog(OperationMeetingListActivity.this, R.string.password);
			alert.setView(passwordTxt);
			alert.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int whichButton) {
					joinMeeting(meetingDto.meetingId, mSkey, passwordTxt.getText().toString(), isOwner);
					dialog.dismiss();
				}
			});
			alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int whichButton) {
					dialog.cancel();
				}
			});
			alert.show();
		} else if (meetingDto.type == MeetingDto.TYPE_OPEN) {
			joinMeeting(meetingDto.meetingId, mSkey, null, isOwner);
		}

		configureViewVisibility();
	}

	private void closeMeetingRoom() {
		mMeetingManager.close();
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			Logger.e(TAG, e);
		}
	}

	/**
	 * 会議室参加
	 *
	 * @param meetingId
	 * @param skey
	 * @param password
	 * @param isOwner
	 */
	private void joinMeeting(int meetingId, String skey, String password, boolean isOwner) {
		try {
			Logger.i("meetingId=" + meetingId + ", skey=" + skey + ", password=" + password + ",isOwner=" + isOwner);
			mMeetingManager.join(meetingId, skey, password, isOwner);
		} catch (Exception e) {
			Logger.e(TAG, "joinMeeting failed. ", e);
			showAlertDialog(R.string.E125);
		}
	}

	/**
	 * 会議室一覧取得
	 */
	private void loadMeetingList() {
		try {
			mSkey = getSessionKey();
			List<MeetingDto> meetingDtoList = getMeetingList(mSkey);
			final TextView noRoomMsgTxt = (TextView) mMeetingListLayout.findViewById(R.id.meeting_no_room_msg); // 一覧
			MeetingDto firstMeetingDto = null;
			if (meetingDtoList != null && meetingDtoList.size() > 0) {
				noRoomMsgTxt.setVisibility(View.GONE);
				// 自分が参加している会議がある場合先頭に持ってくる
                Logger.v(TAG, "meetingManager status=%s meetingId=%s isOwner=%s", mMeetingManager.getStatus(), mMeetingManager.getJoinedMeetingId(), mMeetingManager.isOwner());
				if (mMeetingManager.isConnected()) {
					for (MeetingDto meetingDto : meetingDtoList) {
						if (meetingDto.meetingId == mMeetingManager.getJoinedMeetingId()) {
							firstMeetingDto = meetingDto;
							break;
						}
					}
				}
			}
			
			if (meetingDtoList != null && firstMeetingDto != null) {
				if (mMeetingManager.isConnected() && mMeetingManager.isOwner() && (mMeetingManager.getJoinedMeetingId() == firstMeetingDto.meetingId)) {
						meetingDtoList.remove(firstMeetingDto);
				}
			}
			else {
				if (mMeetingManager.isConnected()) {
					mMeetingManager.setStatus(MeetingManager.STATUS_ENDED);
					handler.postDelayed(new Runnable() {
						@Override
						public void run() {
							showAlertDialog(R.string.msg_meeting_room_deleted);
						}
					}, 1500);
				}
			}
			
			this.mMeetingDtoList = meetingDtoList;
		} catch (NetworkDisconnectedException e) {
			showAlertDialog(R.string.NETWORK);
		} catch (ServerException e) {
			Logger.e(TAG, "deleteMeeting failed", e);
			showErrorMessage(e);
		} catch (Exception e) {
			Logger.e(TAG, "loadMeetingList failed. ", e);
			showAlertDialog(R.string.E127);
		} finally {
			if (mMeetingDtoList == null || mMeetingDtoList.isEmpty()) {
				MeetingDto emptyDto = new MeetingDto();
				emptyDto.isEmptyView = true;
				mMeetingDtoList = new ArrayList<>();
				mMeetingDtoList.add(emptyDto);
			}
		}
	}
	
	private void showAlertDialog(final int resId) {
		if (!isFinishing()) {
			showSimpleAlertDialog(R.string.error, resId);
		}
	}
	
	private List<MeetingDto> getMeetingList(String skey) throws Exception {
		try {
			return mMeetingManager.getMeetingList(skey);
		} catch (HttpUnauthorizedException e) { // skeyがセッション切れの場合再取得
			mSkey = mMeetingManager.getSessionKey(true);
			mActivityHandlingHelper.saveMeetingInfo(mSkey, null, null, null);
			return mMeetingManager.getMeetingList(mSkey);
		}
	}

	/**
	 * SharedPreferencesに保存されているskeyを抽出。
	 * なければ、認証を行って保存する。
	 * 
	 * @return
	 * @throws Exception
	 */
	private String getSessionKey() throws Exception {
    	String skey = getUserPref(UserPrefKey.SKEY, null);
    	if (skey != null) {
    		mMeetingManager.setSkey(skey);
    	}
    	else {
    		skey = mMeetingManager.getSessionKey(false);
    		mActivityHandlingHelper.saveMeetingInfo(skey, null, null, null);
    	}
		
		return skey;
	}

	/**
	 *  会議室作成画面
	 */
	private void createMeetingAddView() {
		mMeetingAddLayout = (LinearLayout) mInflater.inflate(R.layout.ac_projcet_meeting_add, null);

		mCloseBtn = (Button) mMeetingAddLayout.findViewById(R.id.close); // 閉じるボタン
		mCloseBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "mCloseBtn.onClick");
				finish();
				if (isNormalSize()) {
					overridePendingTransition(0, R.anim.view_down);
				}
			}
		});

		mMeetingRoomNameTxt = (EditText) mMeetingAddLayout.findViewById(R.id.meeting_room_name);
		mMeetingRoomPasswordTxt = (EditText) mMeetingAddLayout.findViewById(R.id.meeting_room_password);

		final Button createBtn = (Button) mMeetingAddLayout.findViewById(R.id.create); // 作成ボタン
		createBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "createBtn.onClick");
				String name = mMeetingRoomNameTxt.getText().toString(); // 会議室名
				if (StringUtil.isNullOrWhiteSpace(name)) {
					mMeetingRoomNameTxt.setError(Html.fromHtml("<font color='black'>" + getString(R.string.E121) + "</font>"));
					showIme(mMeetingRoomNameTxt);
					return;
				}
				else if (name.length() > 16) {
					mMeetingRoomNameTxt.setError(Html.fromHtml("<font color='black'>" + getString(R.string.E122) + "</font>"));
					showIme(mMeetingRoomNameTxt);
					return;
				}

				String password = mMeetingRoomPasswordTxt.getText().toString(); // パスワード
				if (!StringUtil.isNullOrEmpty(password)) {
					if (!StringUtil.isHankaku(password, true, true) || password.length() < 3 || password.length() > 10) {
						mMeetingRoomPasswordTxt.setError(Html.fromHtml("<font color='black'>" + getString(R.string.E123) + "</font>"));
						showIme(mMeetingRoomPasswordTxt);
						return;
					}
				}

				InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
				if (imm != null) {
					imm.hideSoftInputFromWindow(v.getWindowToken(), 0); // キーボードを隠す
				}
				Integer meetingId = createMeetingRoom(mMeetingRoomNameTxt.getText().toString(), mMeetingRoomPasswordTxt.getText().toString());
				if (meetingId != null) {
					joinMeeting(meetingId, mSkey, mMeetingRoomPasswordTxt.getText().toString(), true); // 作成と同時に入室して画面を閉じる
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						Logger.e(TAG, e);
					}
					finish();
				}
			}
		});
		setContentView(mMeetingAddLayout);
		mMeetingRoomPasswordTxt.requestFocus();
		mMeetingRoomNameTxt.requestFocus();
	}

	/**
	 * 会議室作成
	 *
	 * @param title
	 * @param password
	 */
	private Integer createMeetingRoom(String title, String password) {
		try {
			return mMeetingManager.createMeeting(mSkey, title, password);
		} catch (ServerException e) {
			Logger.e(TAG, "deleteMeeting failed", e);
			showErrorMessage(e);
		} catch (Exception e) {
			Logger.e(TAG, "createMeetingRoom failed. " + title, e);
			showAlertDialog(R.string.E124);
		}
		return null;
	}

	/**
	 * ボタンの制御
	 */
	private void configureViewVisibility() {
		LinearLayout mMeetingEnteredInfoLayout = (LinearLayout) mMeetingListLayout.findViewById(R.id.entered_meeting_room_layout); // 接続ルーム情報
		TextView titleTxt = (TextView) mMeetingListLayout.findViewById(R.id.meeting_list_title);
		mCloseBtn = (Button) mMeetingListLayout.findViewById(R.id.close);
		if (mMeetingManager.isConnected() && mMeetingManager.isOwner()) { // 開始している場合追加ボタンを非表示
			// リソースパターンの適用
			titleTxt.setText(PatternStringUtil.patternToInt(getApplicationContext(),
								R.string.room_list,
								getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			mMeetingEnteredInfoLayout.setVisibility(View.VISIBLE);

			final MeetingDto enteredMeetingDto = mMeetingManager.getJoinedMeetingDto();
			Logger.v(TAG, "entered_meetingDto " + enteredMeetingDto);

			TextView enteredMeetingIdTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_meeting_id);
			enteredMeetingIdTxt.setText("" + enteredMeetingDto.meetingId);

			TextView enteredParticipantCountTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_participant_count);
			enteredParticipantCountTxt.setText("" + enteredMeetingDto.attendees);

			TextView enteredMeetingRoomNameTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_name);
			enteredMeetingRoomNameTxt.setText(enteredMeetingDto.title);

			TextView enteredCreateDateTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_create_date);
//			String strCreateDate = DateTimeUtil.toString(DateTimeUtil.toDate(enteredMeetingDto.createdate, "UTC", DateTimeFormat.yyyyMMddHHmmss_hyphen), DateTimeFormat.yyyyMMdd_slash);
			enteredCreateDateTxt.setText(enteredMeetingDto.getCreateDateInLocalTime());

			TextView enteredCreatorTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_creator);
			enteredCreatorTxt.setText(enteredMeetingDto.ownerName);

			TextView enteredPasswordSetTxt = (TextView) mMeetingEnteredInfoLayout.findViewById(R.id.entered_room_password_set);
			if (enteredMeetingDto.type == MeetingDto.TYPE_PASSWORD) {
				// リソースパターンの適用
				enteredPasswordSetTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
												R.string.exist,
												getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			} else {
				// リソースパターンの適用
				enteredPasswordSetTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
												R.string.not_exist,
												getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			}

			if (isNormalSize()) {
				int size = 12;
				enteredMeetingIdTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
				enteredMeetingRoomNameTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
				enteredCreatorTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
				enteredCreateDateTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
				enteredParticipantCountTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
				enteredPasswordSetTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
			}

			mAddBtn.setVisibility(View.GONE);
			mLeaveBtn.setVisibility(View.VISIBLE);
		}
		else {
			// リソースパターンの適用
			titleTxt.setText(PatternStringUtil.patternToString(getApplicationContext(),
								R.string.remote_support_list,
								getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
			mAddBtn.setVisibility(View.VISIBLE);
			mMeetingEnteredInfoLayout.setVisibility(View.GONE);
			mLeaveBtn.setVisibility(View.GONE);
		}
	}

	/**
	 * imeを表示する
	 *
	 * @param editText
	 */
	private void showIme(EditText editText) {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		editText.requestFocus();
		if (imm != null) {
			imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); // 一部の端末では閉じてから開かないとうまくいかない
			imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
		}
	}

	/**
	 * WebSocketからのイベントを反映する
	 *
	 * @param message
	 */
	public void update(String message) {
		Logger.v(TAG, "[update]:%s", message);
		if (message.contains("onOpen:101")) { // 入室完了
			handler.post(new Runnable() {
				@Override
				public void run() {
					if (mMeetingManager.isOwner()) {
						finish(); // そのまま閉じるる
					}
					else {
						reloadMeetingList(); // 一覧リロード。退室ボタン以外押下不可。
						if (!mMeetingManager.isEntered(mMeetingDtoList) || !mMeetingManager.isConnected()) {
							handleErrorMessageToast(getString(R.string.msg_disconnected));
							mMeetingManager.close();
						}
					}
				}
			});
		}
		else if (message.contains("onClose:-1")) { // 入室失敗
			handler.post(new Runnable() {
				@Override
				public void run() {
					handleErrorMessageToast(getString(R.string.E125));
					mCloseBtn.setVisibility(View.VISIBLE);
					mAddBtn.setVisibility(View.VISIBLE);
				}
			});
		}
		else if (message.contains("onClose:1000")) { // オーナー側退室
			handler.post(new Runnable() {
				@Override
				public void run() {
					if (!mMeetingManager.isOwner()) {
						finish(); // そのまま閉じるる
					}
				}
			});
		}
		else if (message.contains("onClose:")) { // それ以外のonClose
			handler.post(new Runnable() {
				@Override
				public void run() {
					reloadMeetingList();
				}
			});
		}
	}

	/**
	 *  一覧を再ロード
	 * 
	 */
	public void reloadMeetingList() {
		createMeetingListView();
	}

	/**
	 * サーバのレスポンスコードに応じてエラーメッセージを表示する。
	 * エラー内容はACMSのエラーを流用する。
	 * 
	 * @param e
	 */
	private void showErrorMessage(ServerException e) {
		switch (e.getErrorCode()) {
		case 400:
			showAlertDialog(R.string.S_E_ACMS_0400);
			break;
		case 403:
			showAlertDialog(R.string.S_E_ACMS_0403);
			break;
		case 404:
			showAlertDialog(R.string.S_E_ACMS_0404);
			break;
		case 500:
			showAlertDialog(R.string.S_E_ACMS_0500);
			break;
		default:
			showAlertDialog(R.string.S_E_ACMS_0001);
			break;
		}
	}

}
