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.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

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.view.adapter.MemoryOptionListAdapter;
import com.atid.at288n.app.demo.view.adapter.TagListAdapter;
import com.atid.at288n.app.demo.view.dialog.MaskSelectionDialog;



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

	private TagListAdapter adapterTagList;
	private MemoryOptionListAdapter adapterOption;

	private ArrayAdapter<CharSequence> adapterPowerGain;
	private Spinner spinPowerGain;
	private CheckBox chkUseTid;
	private TextView txtTagCount;
	private Button btnInventory;
	private Button btnMask;
	private Button btnClear;
	private ActionType action = ActionType.Stop;
	private MaskSelectionDialog mask = null;
	private InitChecker initChecker = new InitChecker();
	private boolean enabledWidgets = false;
	
	private ArrayAdapter<CharSequence> adapterReadType;
	private Spinner spinReadType;
	// =================================================================
	// Memory Access Option
	// =================================================================

	public TidView(Context context) {
		super(context);
		init(context);
	}

	public TidView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	private void init(Context context) {
		TAG = "Inventory, TID Access";

		action = ActionType.Stop;

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

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

		if (!initChecker.init)
			return;

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

	@Override
	public void onNothingSelected(AdapterView<?> parent) {
	}

	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 onCreate(IReaderActivity parent, Reader reader) {
		super.onCreate(parent, reader);

		// Initialize Title
		title = getResources().getString(R.string.tid_opt_label);
		icon = R.drawable.ic_inventory;

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

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

	@Override
	public void onClick(View v) {
		Log.d(TAG, String.format("onClick(%d)", v.getId()));

		switch (v.getId()) {
		case R.id.display_tid:
			this.adapterTagList.setDisplayTid(this.chkUseTid.isChecked());
			break;
		case R.id.read_inventory:
			if (ActionType.Stop == this.action) {
				if (mask.getMask().equals("")) {
					reader.inventoryMemory(adapterOption.getBank(), adapterOption.getOffset(), adapterOption.getLength(), null);
				} else {
					reader.inventoryMemory(adapterOption.getBank(), adapterOption.getOffset(), adapterOption.getLength(), mask.getMask());
				}
				this.action = ActionType.Inventory;
			} else {
				reader.stopOperation();
				this.action = ActionType.Stop;
			}
			enableWidget(true);
			break;
		case R.id.clear:
			clearTagList();
			break;
		case R.id.mask:
			if(adapterTagList.getCount()> 0){
				//String strTag = adapterTagList.getTag(1);
			}
			mask.show();
			break;
		}
	}

	@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 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 All Extended Properties
		reader.getAllExtendedProperty();
		// 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));

		adapterTagList.addTag(tag);

		txtTagCount.setText("" + adapterTagList.getCount());
	}

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

	@Override
	public void onReaderProperty(char code, String value) {
		Log.d(TAG, String.format("onReaderProperty(%c, %s)", code, value));

		switch (code) {
		case Reader.PROPERTY_CONTINUE_MODE:
			break;
		case Reader.PROPERTY_SELECTION_BANK:
			mask.setBank(BankType.valueOf(Integer.parseInt(value)));
			checkInit(InitChecker.BANK);
			break;
		case Reader.PROPERTY_SELECTION_OFFSET:
			mask.setOffset(Integer.parseInt(value));
			checkInit(InitChecker.OFFSET);
			break;
		case Reader.PROPERTY_SELECTION_ACTION:
			mask.setAction(SelectionActionType.valueOf(Integer.parseInt(value)));

			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_STOP:
			action = ActionType.Stop;
			break;
		default:
			action = ActionType.Inventory;
			break;
		}
		enableWidget(true);
	}

	@Override
	public void onReaderExtentedProperty(char code, String value) {
		Log.d(TAG,
				String.format("onReaderExtendedProperty(%c, %s)", code, value));
		enableWidget(true);

		switch (code) {
		case Reader.PROPERTY_EX_POWER_GAIN:
			spinPowerGain.setSelection(Integer.parseInt(value));
			checkInit(InitChecker.POWER);
			break;
		case Reader.PROPERTY_EX_USE_SERIAL_NO:
			checkInit(InitChecker.USE_SERIAL_NO);
			break;
		case Reader.PROPERTY_EX_CONTINUE_MODE:
			spinReadType.setSelection(Integer.parseInt(value));
			if(spinReadType.getCount() >=3 && reader.IsAT288N_MA()) {
				this.spinReadType.setAdapter(null);
				this.adapterReadType = ArrayAdapter.createFromResource(getContext(),
						R.array.read_type_array_ma,
						android.R.layout.simple_spinner_dropdown_item);
				this.spinReadType.setAdapter(this.adapterReadType);
			}
			checkInit(InitChecker.CONTINUE_MODE);
			break;
		case Reader.PROPERTY_EX_TAG_TYPE:
			if(reader.TagType == Reader.ISO18000_6B){
				enableWidget(false);
			}else{
				enableWidget(true);
			}
			break;
		}
	}

	@Override
	public void onReaderTimeout() {
	}

	// =================================================================
	// MainActivity Widget Control Methods
	// =================================================================
	// Initialize Widget
	private void initWidget() {
		ListView listView = null;
		
		
		// Initialize tag listview
		this.adapterTagList = new TagListAdapter(getContext());
		ListView lstTag = (ListView) findViewById(R.id.tag_list);
		lstTag.setAdapter(adapterTagList);
		lstTag.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

		// 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 tid mode checkbox
		this.chkUseTid = (CheckBox) findViewById(R.id.display_tid);
		this.chkUseTid.setOnClickListener(this);

		// Initialize tag count textview
		this.txtTagCount = (TextView) findViewById(R.id.tag_count);

		// Initialize inventory button
		this.btnInventory = (Button) findViewById(R.id.read_inventory);
		this.btnInventory.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);
		
		// Initialize option list view
		this.adapterOption = new MemoryOptionListAdapter(getContext());
		listView = (ListView) findViewById(R.id.memory_option);
		listView.setAdapter(adapterOption);
		listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		listView.setOnItemClickListener(this);
		
		// Initialize InventoryFormat spinner
		this.spinReadType = (Spinner) findViewById(R.id.spin_read_type);
		this.spinReadType.setPrompt(getResources().getString(
				R.string.read_type_prompt_label));
		this.spinReadType.setOnItemSelectedListener(this);
		this.adapterReadType = ArrayAdapter.createFromResource(getContext(),
				R.array.read_type_array,
				android.R.layout.simple_spinner_dropdown_item);
		this.spinReadType.setAdapter(this.adapterReadType);
	}

	public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
		if (!this.enabledWidgets)
			return;

		AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
		switch (position) {
		case MemoryOptionListAdapter.BANK:
			builder.setTitle(getResources().getString(
					R.string.bank_type_prompt_label));
			builder.setSingleChoiceItems(R.array.bank_type_array, adapterOption
					.getBank().value(), new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					adapterOption.setBank(BankType.valueOf(which));
					dialog.cancel();
				}

			});
			break;
		case MemoryOptionListAdapter.OFFSET:
			builder.setTitle(getResources().getString(
					R.string.start_address_prompt_label));
			builder.setSingleChoiceItems(R.array.memory_offset_array,
					adapterOption.getOffset(),
					new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							adapterOption.setOffset(which);
							dialog.cancel();
						}

					});
			break;
		case MemoryOptionListAdapter.LENGTH:
			builder.setTitle(getResources().getString(
					R.string.read_length_prompt_label));
			builder.setSingleChoiceItems(R.array.memory_length_array,
					adapterOption.getLength() - 1,
					new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							adapterOption.setLength(which + 1);
							dialog.cancel();
						}

					});
			break;
		case MemoryOptionListAdapter.PASSWORD:
			final LinearLayout linear = (LinearLayout) View.inflate(
					getContext(), R.layout.dialog_access_password, null);
			final EditText txtPassword = (EditText) linear
					.findViewById(R.id.password);

			builder.setTitle(getResources().getString(
					R.string.password_prompt_label));
			builder.setView(linear);
			builder.setPositiveButton(R.string.ok_button_label,
					new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							adapterOption.setPassword(txtPassword.getText()
									.toString());
							reader.setAccessPassword(adapterOption.getPassword());
							dialog.cancel();
						}
					});
			break;
		}
		builder.setNegativeButton(
				getResources().getString(R.string.cancel_button_label), null);
		builder.show();
	}
	
	// Enable Widget
	private void enableWidget(boolean enabled) {
		
		if (enabled) {
			if (this.action == ActionType.Stop) {
				enabledWidgets = true;
				this.spinPowerGain.setEnabled(true);
				this.chkUseTid.setEnabled(true);
				this.btnInventory.setText(getResources().getString(
						R.string.read_inventory_button_label));
				this.btnInventory.setEnabled(true);
				this.btnClear.setEnabled(true);
				this.btnMask.setEnabled(true);
				this.spinReadType.setEnabled(true);
			} else {
				enabledWidgets = false;
				this.spinPowerGain.setEnabled(false);
				this.spinReadType.setEnabled(false);
				this.chkUseTid.setEnabled(false);
				this.btnInventory.setText(getResources().getString(
						R.string.stop_button_label));
				this.btnInventory.setEnabled(true);
				this.btnClear.setEnabled(false);
				this.btnMask.setEnabled(false);
			}
		} else {
			enabledWidgets = false;
			this.spinPowerGain.setEnabled(false);
			this.spinReadType.setEnabled(false);
			this.chkUseTid.setEnabled(false);
			this.btnInventory.setEnabled(false);
			this.btnClear.setEnabled(false);
			this.btnMask.setEnabled(false);
		}
	}

	// Clear Tag List View
	private void clearTagList() {
		// Tag infomation
		this.adapterTagList.clear();
		this.txtTagCount.setText("" + this.adapterTagList.getCount());
	}

	// 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 CONTINUE_MODE = 1;
		public static final int BANK = 2;
		public static final int OFFSET = 3;
		public static final int ACTION = 4;
		public static final int USE_SERIAL_NO = 5;
		public static final int STORED_MODE = 6;

		public boolean init;
		public boolean[] check;

		public InitChecker() {
			init();
		}

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

		private boolean isInitialized() {
			//ATLog.e(TAG, "(%s, %s, %s, %s, %s, %s, %s)",check[0],check[1],check[2],check[3],check[4],check[5],check[6]);
			return !init && check[0] && check[1] && check[2] && check[3]
					&& check[4] && check[5] && check[6];
		}
	}
	
	private class InitTask extends AsyncTask<Void, Void, Void> {

		private Context context = TidView.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();
		}
	}

}
