package com.atid.at288n.app.demo.view;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.atid.at288.lib.Reader;
import com.atid.at288.lib.type.BankType;
import com.atid.at288.lib.type.SelectionActionType;
import com.atid.at288n.app.demo.IReaderActivity;
import com.atid.at288n.app.demo.R;
import com.atid.at288n.app.demo.dialog.WaitDialog;
import com.atid.at288n.app.demo.type.ActionType;
import com.atid.at288n.app.demo.type.LockType;
import com.atid.at288n.app.demo.view.adapter.AccessOptionListAdapter;
import com.atid.at288n.app.demo.view.dialog.MaskSelectionDialog;

public class AccessView extends BaseView implements Button.OnClickListener,
		OnItemClickListener, OnItemSelectedListener {

	// =================================================================
	// Declare Member Variable
	// =================================================================

	private ProgressBar progress;
	private TextView message;

	private AccessOptionListAdapter adapterOption;

	private EditText edtAccessPassword;
	private EditText edtKillPassword;

	private ArrayAdapter<CharSequence> adapterPowerGain;
	private Spinner spinPowerGain;

	private Button btnLock;
	private Button btnKill;
	private Button btnClear;
	private Button btnMask;

	private ActionType action = ActionType.Stop;
	private MaskSelectionDialog mask = null;
	private boolean enabledWidgets = false;
	private InitChecker initChecker = new InitChecker();

	public AccessView(Context context) {
		super(context);
		if (isInEditMode())
			return;
		init(context);
	}

	public AccessView(Context context, AttributeSet attrs) {
		super(context, attrs);
		if (isInEditMode())
			return;
		init(context);
	}

	private void init(Context context) {
		TAG = "AccessView";

		action = ActionType.Stop;

		if (!isInEditMode()) {
			LayoutInflater inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			inflater.inflate(R.layout.view_access, this, true);
		}
	}

	@Override
	public void onCreate(IReaderActivity parent, Reader reader) {
		super.onCreate(parent, reader);

		title = getResources().getString(R.string.tag_access_title);
		icon = R.drawable.ic_tag_access;

		// Initialize Widget
		initWidget();
		// Disable Widget
		enableWidget(false);

		mask = new MaskSelectionDialog(getContext(), maskListener);
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.lock:
			if (ActionType.Stop == this.action) {

				if(!edtAccessPassword.getText().toString().equals("")) {
					if (edtAccessPassword.getText().toString().length() != 8) {
						Toast.makeText(getContext(), "Access PWD's length is must be 8", Toast.LENGTH_SHORT).show();
						return;
					}
					reader.setAccessPassword(edtAccessPassword.getText().toString());
				} else {
					reader.setAccessPassword(getResources().getString(R.string.default_access_password));
				}
				if (mask.getMask().equals("")) {
					reader.lock(adapterOption.getMask(),
							adapterOption.getAction());
				} else {
					reader.lock(adapterOption.getMask(),
							adapterOption.getAction(), mask.getMask());
				}
				displayMessage(
						getResources().getString(R.string.access_lock_label),
						true);
			} else {
				reader.stopOperation();
				displayMessage(getResources().getString(R.string.stop_msg),
						false);
			}
			enableWidget(false);
			break;
		case R.id.kill:
			if (ActionType.Stop == this.action) {
				
				if(edtKillPassword.getText().toString().length() != 8) {
					Toast.makeText(getContext(), "Kill PWD's length is must be 8", Toast.LENGTH_SHORT).show();
					return;
				}
				
				if (mask.getMask().equals("")) {
					reader.kill(edtKillPassword.getText().toString());
				}else{
					reader.kill(edtKillPassword.getText().toString(),mask.getMask());
				}
				
				displayMessage(
						getResources().getString(R.string.access_kill_label),
						true);
			} else {
				reader.stopOperation();
				displayMessage(getResources().getString(R.string.stop_msg),
						false);
			}
			enableWidget(false);
			break;
		case R.id.clear:
			clearTagList();
			break;
		case R.id.mask:
			mask.show();
			break;
		}
	}

	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int position,
			long id) {
		Log.d(TAG, String.format("onItemSelected(%d, %d, %d)", parent.getId(),
				position, id));

		if (!initChecker.init)
			return;

		switch (parent.getId()) {
		case R.id.power_gain:
			// Change Power Gain...
			reader.setPowerEx(position);
			break;
		}
	}

	@Override
	public void onNothingSelected(AdapterView<?> parent) {
		Log.d(TAG, String.format("onNothingSelected(%d)", parent.getId()));
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		Log.d(TAG, String.format("onItemClick(%d, %d, %d)", parent.getId(),
				position, id));

		final int pos = position;

		if (!this.enabledWidgets)
			return;

		AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
		builder.setTitle(getResources().getString(
				R.string.bank_type_prompt_label));
		builder.setSingleChoiceItems(R.array.lock_type_array, adapterOption
				.getLock(position).value(),
				new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog, int which) {
						adapterOption.setLock(pos, LockType.valueOf(which));
						dialog.cancel();
					}
				});
		builder.setNegativeButton(
				getResources().getString(R.string.cancel_button_label), null);
		builder.show();
	}

	DialogInterface.OnClickListener maskListener = new DialogInterface.OnClickListener() {

		@Override
		public void onClick(DialogInterface dialog, int which) {
			reader.setSelectionBank(mask.getBank());
			reader.setSelectionOffset(mask.getOffset());
			reader.setSelectionAction(mask.getAction());
			mask.setMask(mask.getMask());
		}
	};

	@Override
	public void initView() {
		// Initalize Checker
		initChecker.init();
		// Enable Activity Widget
		enableWidget(false);
		// Clear Tag List
		clearTagList();

		InitTask requestParamsTask = new InitTask();
		requestParamsTask.execute();
		
	}
	
	public void requestParameters() {
		// Set Continue Mode
		reader.setContinueMode(false);
		// Set Use Serial No
		reader.setUseSerialNo(false);
		// Set Access Password
		reader.setAccessPassword("");
		// Set Mask Memory Bank
		reader.setSelectionBank(mask.getBank());
		// Set Mask Offset
		reader.setSelectionOffset(mask.getOffset());
		// Set Mask Action
		reader.setSelectionAction(mask.getAction());

		// Request Global Band
		reader.getGlobalBand();
		// Request Power Gain
		reader.getPowerEx();
		// Request Mask Memory Bank
		reader.getSelectionBank();
		// Request Mask Offset
		reader.getSelectionOffset();
		// Request Mask Action
		reader.getSelectionAction();
	}

	@Override
	public void exitView() {
		reader.stopOperation();
		this.action = ActionType.Stop;
		enableWidget(true);
	}

	@Override
	public void createView() {
	}

	public void createView(int Globalband) {
		
		if(adapterPowerGain != null) {
			return;
		}

		if (Globalband == 8)//Japan 1W 
		{
			adapterPowerGain = ArrayAdapter.createFromResource(getContext(),
							R.array.power_gain_array,
							android.R.layout.simple_spinner_dropdown_item);
		}
		else if (Globalband == 9)//Japan 0.25W
		{
			adapterPowerGain = ArrayAdapter.createFromResource(getContext(), 
							R.array.power_gain_japan_array,
							android.R.layout.simple_spinner_dropdown_item);
		}
		else if (Globalband == 12)//Japan 0.125W
		{
			adapterPowerGain = ArrayAdapter.createFromResource(getContext(), 
							R.array.power_gain_japan_array_125,
							android.R.layout.simple_spinner_dropdown_item);
		}
		else					//Normal
		{
			adapterPowerGain = ArrayAdapter.createFromResource(getContext(), 
							R.array.power_gain_array,
							android.R.layout.simple_spinner_dropdown_item);
		}
		
		spinPowerGain.setAdapter(adapterPowerGain);
	}

	@Override
	public void onReaderStateChange(int state) {
		Log.d(TAG, String.format("onReaderStateChange(%d)", state));
		if (state == Reader.STATE_LISTEN || state == Reader.STATE_NONE)
			parent.closeSubView();
	}

	@Override
	public void onReaderReadTag(int event, String tag) {
		Log.d(TAG, String.format("onReaderReadTag(%d, %s)", event, tag));
	}

	@Override
	public void onReaderResponse(int event, String code) {
		Log.d(TAG, String.format("onReaderResponse(%d, %s)", event, code));
		displayMessage(code);
		reader.stopOperation();
		action = ActionType.Stop;
		enableWidget(true);
		Log.e(TAG, "+ setAccessPassword");
		reader.setAccessPassword(getResources().getString(R.string.default_access_password));
		Log.e(TAG, "- setAccessPassword");
	}

	@Override
	public void onReaderProperty(char code, String value) {
		Log.d(TAG, String.format("onReaderProperty(%c, %s)", code, value));
		int val = 0;
		switch (code) {
		case Reader.PROPERTY_SELECTION_BANK:
			val = Integer.parseInt(value);
			mask.setBank(BankType.valueOf(val));
			checkInit(InitChecker.BANK);
			break;
		case Reader.PROPERTY_SELECTION_OFFSET:
			val = Integer.parseInt(value);
			mask.setOffset(val);
			checkInit(InitChecker.OFFSET);
			break;
		case Reader.PROPERTY_SELECTION_ACTION:
			val = Integer.parseInt(value);
			mask.setAction(SelectionActionType.valueOf(val));
			checkInit(InitChecker.ACTION);
			break;
		case Reader.PROPERTY_GLOBAL_BAND:
			int globalBand = Integer.parseInt(value);
			createView(globalBand);
			break;
		}
	}

	@Override
	public void onReaderAction(char code) {
		Log.d(TAG, String.format("onReaderActionChange(%c)", code));
		
		switch(code) {
		case Reader.ACTION_INVENTORY_6B_MULTIPLE:
		case Reader.ACTION_INVENTORY_6B_SINGLE:
		case Reader.ACTION_INVENTORY_6C_MULTIPLE:
		case Reader.ACTION_INVENTORY_6C_SELECTION:
		case Reader.ACTION_INVENTORY_6C_SINGLE:
		case Reader.ACTION_INVENTORY_6C_VLC:
			enableWidget(false);
			break;
		case Reader.ACTION_STOP:
			this.action = ActionType.Stop;
			enableWidget(true);
			Log.e(TAG, "!!! Stop");
			break;
		case Reader.ACTION_LOCK:
			this.action = ActionType.Lock;
			enableWidget(true);
			Log.e(TAG, "!!! Lock");
			break;
		case Reader.ACTION_KILL:
			this.action = ActionType.Kill;
			enableWidget(true);
			break;
		}
	}

	@Override
	public void onReaderExtentedProperty(char code, String value) {
		Log.d(TAG,
				String.format("onReaderExtendedProperty(%c, %s)", code, value));
		int val = Integer.parseInt(value);
		switch (code) {
		case Reader.PROPERTY_EX_POWER_GAIN:
			spinPowerGain.setSelection(val);
			checkInit(InitChecker.POWER);
			break;
		case Reader.PROPERTY_EX_TAG_TYPE:
			if(reader.TagType == Reader.ISO18000_6B){
				enableWidget(false);
			}else{
				enableWidget(true);
			}
			break;
		}
	}

	@Override
	public void onReaderTimeout() {
		Log.d(TAG, "onReaderTimeout()");
		displayMessage("TIMEOUT");
		reader.stopOperation();
		action = ActionType.Stop;
		enableWidget(true);
	}

	// =================================================================
	// MainActivity Widget Control Methods
	// =================================================================

	// Initialize Widget
	private void initWidget() {
		ListView listView = null;

		// Initialize progress bar
		this.progress = (ProgressBar) findViewById(R.id.progress_bar);

		// Initialize message text view
		this.message = (TextView) findViewById(R.id.access_msg);

		// Initialize option list view
		this.adapterOption = new AccessOptionListAdapter(getContext());
		listView = (ListView) findViewById(R.id.access_option);
		listView.setAdapter(adapterOption);
		listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		listView.setOnItemClickListener(this);

		// Initialize access password edit text
		this.edtAccessPassword = (EditText) findViewById(R.id.access_password);

		// Initialize kill password edit text
		this.edtKillPassword = (EditText) findViewById(R.id.kill_password);

		// Initialize power gain spinner
		this.spinPowerGain = (Spinner) findViewById(R.id.power_gain);
		this.spinPowerGain.setPrompt(getResources().getString(
				R.string.power_gain_prompt_label));
		this.spinPowerGain.setOnItemSelectedListener(this);

		// Initialize lock button
		this.btnLock = (Button) findViewById(R.id.lock);
		this.btnLock.setOnClickListener(this);

		// Initlaiize kill button
		this.btnKill = (Button) findViewById(R.id.kill);
		this.btnKill.setOnClickListener(this);

		// Initialize clear button
		this.btnClear = (Button) findViewById(R.id.clear);
		this.btnClear.setOnClickListener(this);

		// Initialize mask button
		this.btnMask = (Button) findViewById(R.id.mask);
		this.btnMask.setOnClickListener(this);
	}

	// Enable Widget
	private void enableWidget(boolean enabled) {
		ListView listView = (ListView) findViewById(R.id.access_option);

		if (enabled) {
			if (this.action == ActionType.Lock) {
				enabledWidgets = false;
				listView.setEnabled(false);
				this.edtAccessPassword.setEnabled(false);
				this.edtKillPassword.setEnabled(false);
				this.spinPowerGain.setEnabled(false);
				this.btnLock.setText(getResources().getString(
						R.string.stop_button_label));
				this.btnLock.setEnabled(true);
				this.btnKill.setEnabled(false);
				this.btnClear.setEnabled(false);
				this.btnMask.setEnabled(false);
			} else if (this.action == ActionType.Kill) {
				enabledWidgets = false;
				listView.setEnabled(false);
				this.edtAccessPassword.setEnabled(false);
				this.edtKillPassword.setEnabled(false);
				this.spinPowerGain.setEnabled(false);
				this.btnKill.setText(getResources().getString(
						R.string.stop_button_label));
				this.btnLock.setEnabled(false);
				this.btnKill.setEnabled(true);
				this.btnClear.setEnabled(false);
				this.btnMask.setEnabled(false);
			} else {
				enabledWidgets = true;
				listView.setEnabled(true);
				this.edtAccessPassword.setEnabled(true);
				this.edtKillPassword.setEnabled(true);
				this.spinPowerGain.setEnabled(true);
				btnLock.setEnabled(true);
				this.btnLock.setText(getResources().getString(
						R.string.lock_button_label));
				this.btnKill.setText(getResources().getString(
						R.string.kill_button_label));
				this.btnClear.setEnabled(true);
				this.btnMask.setEnabled(true);
				if(reader.IsAT288N_MA())
					this.btnKill.setEnabled(false);
				else this.btnKill.setEnabled(true);
			}
		} else {
			enabledWidgets = false;
			listView.setEnabled(false);
			this.edtAccessPassword.setEnabled(false);
			this.edtKillPassword.setEnabled(false);
			this.spinPowerGain.setEnabled(false);
			this.btnLock.setEnabled(false);
			this.btnKill.setEnabled(false);
			this.btnClear.setEnabled(false);
			this.btnMask.setEnabled(false);
		}
	}

	// Clear Tag List View
	private void clearTagList() {
		this.adapterOption.clear();
		this.edtAccessPassword.setText("");
		this.edtKillPassword.setText("");
		displayMessage(getResources().getString(R.string.access_intro_label),
				false);
	}

	private void displayMessage(String msg, boolean showProgress) {
		progress.setVisibility(showProgress ? View.VISIBLE : View.GONE);
		message.setText(msg);
		message.setTextColor(getResources().getColor(R.color.black));
		message.setBackgroundColor(getResources().getColor(
				R.color.message_background));
	}

	private void displayMessage(String code) {
		int backColor = 0;
		String msg;

		if (code.equals("TIMEOUT")) {
			msg = getResources().getString(R.string.timeout_title);
			backColor = getResources().getColor(R.color.red);
		} else if (code.equals("01")) {
			msg = Reader.getResponses(code);
			backColor = getResources().getColor(R.color.blue);
		} else {
			msg = Reader.getResponses(code);
			backColor = getResources().getColor(R.color.red);
		}
		progress.setVisibility(View.GONE);
		message.setText(msg);
		message.setTextColor(getResources().getColor(R.color.white));
		message.setBackgroundColor(backColor);
	}

	// Check Initialize Reader Service
	private void checkInit(int index) {
		if (initChecker.init)
			return;

		initChecker.check[index] = true;
		if (initChecker.isInitialized()) {
			initChecker.init = true;
			enableWidget(true);
			WaitDialog.hide();
		}
	}

	// =================================================================
	// Declare Internal Classes
	// =================================================================

	private class InitChecker {
		public static final int POWER = 0;
		public static final int BANK = 1;
		public static final int OFFSET = 2;
		public static final int ACTION = 3;

		public boolean init;
		public boolean[] check;

		public InitChecker() {
			init();
		}
		
		public void init() {
			init = false;
			check = new boolean[] { false, false, false, false };
		}

		private boolean isInitialized() {
			return !init && check[0] && check[1] && check[2] && check[3];
		}
	}
	
	private class InitTask extends AsyncTask<Void, Void, Void> {

		private Context context = AccessView.this.getContext();
		ProgressDialog asyncDialog = new ProgressDialog(context);
		
		@Override
		protected void onPreExecute() {
			asyncDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			asyncDialog.setMessage("wait for initialize");
			asyncDialog.setCancelable(false);
			asyncDialog.show();
			super.onPreExecute();
		}

		@Override
		protected Void doInBackground(Void... params) {
			
			requestParameters();
			
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			asyncDialog.dismiss();
			super.onPostExecute(result);
		}
		
	}

	@Override
	public void clearMaskParams() {
		if(mask != null) {
			mask.resetContents();
		}
	}
}
