package com.atid.app.atx.ble.deviceoption.dialog;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.atid.app.atx.ble.deviceoption.R;
import com.atid.lib.reader.params.NotifyMethod;
import com.atid.lib.types.DeviceType;
import com.atid.lib.util.diagnotics.ATLog;

import java.util.ArrayList;

public class NotifyMethodDialog extends BaseDialog {

	private static final String TAG = NotifyMethodDialog.class.getSimpleName();
	private static final int INFO = ATLog.L2;

	private NotifyMethod mMethod;
	private NotifyMethod mOldMethod;

	private DeviceType mDeviceType;
	private NotifyMethodAdapter mAdapter;
	
	public NotifyMethodDialog() {
		super();
		mMethod = new NotifyMethod();
		mOldMethod = new NotifyMethod();
		mDeviceType = DeviceType.Unknown;
	}

	public NotifyMethodDialog(DeviceType type) {
		super();
		mMethod = new NotifyMethod();
		mOldMethod = new NotifyMethod();
		mDeviceType = type;
	}

	public NotifyMethodDialog(TextView view) {
		super(view);
		mMethod = new NotifyMethod();
		mOldMethod = new NotifyMethod();
		mDeviceType = DeviceType.Unknown;
	}
	
	public NotifyMethodDialog(DeviceType type, TextView view) {
		super(view);
		mMethod = new NotifyMethod();
		mOldMethod = new NotifyMethod();
		mDeviceType = type;
	}

	public void setDeviceType(DeviceType type) {
		mDeviceType = type;
	}
	
	public NotifyMethod getMethod() {
		return mMethod;
	}

	public void setMethod(NotifyMethod method) {
		
		for (int i = 0; i < NotifyMethod.MAX_METHOD ; i++) {
			mMethod.setMethods(i, method.getMethod(i));
			mOldMethod.setMethods(i, method.getMethod(i));
		}
	}

	public void restoreMethod() {
		
		for (int i = 0; i < NotifyMethod.MAX_METHOD ; i++)
			mMethod.setMethods(i, mOldMethod.getMethod(i));
			
		display();
	}

	@Override
	public void display() {
		if (txtValue == null)
			return;
		txtValue.setText(mMethod.toString());
	}

	@Override
	public void showDialog(Context context, String title, final IValueChangedListener changedListener,
			final ICancelListener cancelListener) {

		if (txtValue != null) {
			if (!txtValue.isEnabled())
				return;
		}

		LinearLayout root = (LinearLayout) LinearLayout.inflate(context, R.layout.dialog_list_view, null);
		final ListView list = (ListView) root.findViewById(R.id.list);
		
		mAdapter = new NotifyMethodAdapter(context, context.getResources().getStringArray(R.array.notify_method));
		list.setAdapter(mAdapter);

		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setTitle(title);
		builder.setView(root);
		builder.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {

			@SuppressWarnings("static-access")
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				for (int i = 0 ; i < mMethod.MAX_METHOD ; i++) {
					mMethod.setMethods(i, mAdapter.getChecked(i));
				}
				
				display();
				if (changedListener != null) {
					changedListener.onValueChanged(NotifyMethodDialog.this);
				}
				ATLog.i(TAG, INFO, "INFO. showDialog().$PositiveButton.onClick()");
			}
		});
		builder.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if (cancelListener != null) {
					cancelListener.onCanceled(NotifyMethodDialog.this);
				}
				ATLog.i(TAG, INFO, "INFO. showDialog().$NegativeButton.onClick()");
			}
		});

		builder.setCancelable(true);
		builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
			
			@Override
			public void onCancel(DialogInterface dialog) {
				if (cancelListener != null) {
					cancelListener.onCanceled(NotifyMethodDialog.this);
				}
				ATLog.i(TAG, INFO, "INFO. showDialog().onCancel()");
			}
		});
		AlertDialog dialog = builder.create();
		dialog.setOnShowListener(new DialogInterface.OnShowListener() {

			@Override
			public void onShow(DialogInterface dialog) {

				for (int i = 0; i < NotifyMethod.MAX_METHOD; i++) {
					mAdapter.setChecked(i, mMethod.getMethod(i));
				}
				mAdapter.notifyDataSetChanged();
				
				ATLog.i(TAG, INFO, "INFO. showDialog().onShow()");
			}
		});
		dialog.setCanceledOnTouchOutside(false);
		dialog.show();

		ATLog.i(TAG, INFO, "INFO. showDialog()");
	}
	
	private class NotifyMethodAdapter extends BaseAdapter {
		
		private LayoutInflater mInflater;
		private ArrayList<NotifyMethodItem> mItems;
		
		private NotifyMethodAdapter(Context context, String[] names) {
			super();
			
			mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			mItems = new ArrayList<NotifyMethodItem>();
			for (int i=0; i< names.length ; i++) {
				mItems.add(new NotifyMethodItem(i, names[i]));
				if (mDeviceType == DeviceType.ATD100) {
					if ( i == NotifyMethod.VIBRATE) {
						mItems.get(i).IsEnabled = false;
					} else {
						mItems.get(i).IsEnabled = true;
					}
				} else if (mDeviceType == DeviceType.ATS100 || mDeviceType == DeviceType.ATS200) {
					if ( i == NotifyMethod.LIGHT ) {
						mItems.get(i).IsEnabled = false;
					} else {
						mItems.get(i).IsEnabled = true;
					}
				} else {
					mItems.get(i).IsEnabled = true;
				}
			}
		}
		
		public void setChecked(int position, boolean isEnabled) {
			mItems.get(position).IsUsed = isEnabled;
		}
		
		public boolean getChecked(int position) {
			return mItems.get(position).IsUsed;
		}
		
		@Override
		public int getCount() {
			return mItems.size();
		}
		
		@Override
		public String getItem(int position) {
			return mItems.get(position).Name;
		}
		
		@Override
		public long getItemId(int position) {
			return position;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			NotifyMethodViewHolder holder = null;
			
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.item_notify_method, parent, false);
				holder = new NotifyMethodViewHolder(convertView, mItems.get(position));
			} else {
				holder = (NotifyMethodViewHolder) convertView.getTag();
			}
			holder.display(position, mItems.get(position));
			
			return convertView;
		}
		
		private class NotifyMethodViewHolder implements OnCheckedChangeListener {
			private int mPosition;
			private CheckBox chkUsed;
			private TextView txtName;
			
			private NotifyMethodViewHolder(View parent) {
				mPosition = -1;
				chkUsed = (CheckBox) parent.findViewById(R.id.used);
				chkUsed.setEnabled(true);
				chkUsed.setOnCheckedChangeListener(this);
				txtName = (TextView) parent.findViewById(R.id.name);
				txtName.setEnabled(true);
				parent.setTag(this);
			}

			private NotifyMethodViewHolder(View parent, NotifyMethodItem item) {
				mPosition = -1;
				chkUsed = (CheckBox) parent.findViewById(R.id.used);
				chkUsed.setEnabled(item.IsEnabled);
				chkUsed.setOnCheckedChangeListener(this);
				txtName = (TextView) parent.findViewById(R.id.name);
				txtName.setEnabled(item.IsEnabled);
				parent.setTag(this);
				
			}

			private void display(int position, NotifyMethodItem item) {
				mPosition = position;
				chkUsed.setChecked(item.IsUsed);
				txtName.setText(item.Name);
			}
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				mItems.get(mPosition).IsUsed = isChecked;
				ATLog.i(TAG, INFO, "INFO. $NotifyMethodViewHolder.onCheckedChanged() - [%d, %s]", mPosition, isChecked);
			}
			
		}
		private class NotifyMethodItem {
			public String Name;
			public boolean IsUsed;
			public boolean IsEnabled;
			
			private NotifyMethodItem(int position, String name) {
				Name = name;
			}
		}
	}
}
