package org.arkiwi.app.activity;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import org.arkiwi.app.R;
import org.arkiwi.app.interfaces.Define;
import org.arkiwi.app.interfaces.SDialogInterface;
import org.arkiwi.app.utility.IcoCtxMenu;
import org.arkiwi.app.utility.SDialog;
import org.arkiwi.app.utility.SMethod;

import android.os.Bundle;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class SearchAdv extends Activity implements SDialogInterface, Define {
	private static final String LOG_TAG = "SearchAdv";
	private static Resources res;
	private static Activity activity;
	private static InputMethodManager imm;
	//Oggetti dell'activity
	private static CheckBox  
		dir , audio, video;
	private static Dialog dialog;
	private static SubMenu subMenu;
	private static LinearLayout etGrp;
	private static Spinner spinner;
	private static Button btn;
	private static TextView tv_help;
	private static String[] spinner_label;
	private final static String[] spinnkeyar = 
		{A_KEY_TITLE,A_KEY_DESC,A_KEY_AUTHOR,A_KEY_PUB,A_KEY_COVER,A_KEY_DATE,
		  A_KEY_LUNG,A_KEY_SIZE,A_KEY_TAGS,A_KEY_TRACK,A_KEY_ALBUM,A_KEY_YEAR};
	// date and time
	private static int mYear, mMonth, mDay;
	//Gestione menu' contestuale ottenuto con Dialog
	private static View itemLClicked = null;
	private static IcoCtxMenu 
			icoCtxMenuAnd, 
			icoCtxMenuOr;
	private static final int
			MENUCTX_ITEM_AND = 0,
			MENUCTX_ITEM_OR = 1,
			MENUCTX_ITEM_DELETE = 3,
			MENUCTX_ITEM_VOID = 4,
			// Menu
			MENU_CLEANALL_ID = 10,
			MENU_HELP_ID = 11,
			MENU_CONGEN_ID = 12;
	public int gcong;
			
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search_adv_main);

		res = getResources();
		activity = this;
		imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		etGrp = (LinearLayout) findViewById(R.id.adv_search_etContainer);
		spinner = (Spinner) findViewById(R.id.spinner_metatag);
		spinner_label = getResources().getStringArray(R.array.search_adv);
		tv_help = (TextView) etGrp.findViewById(R.id.metatag_help);
		btn = (Button) findViewById(R.id.adv_search_btn);
		dir = (CheckBox) findViewById(R.id.mediat_dir);
		audio = (CheckBox) findViewById(R.id.mediat_audio);
		video = (CheckBox) findViewById(R.id.mediat_video);
		gcong = MENUCTX_ITEM_AND;
		
		final Calendar c = Calendar.getInstance();
		mYear = c.get(Calendar.YEAR);
		mMonth = c.get(Calendar.MONTH);
		mDay = c.get(Calendar.DAY_OF_MONTH);
		
		icoCtxMenuOr = new IcoCtxMenu(this, CTX_MENU_SADV_OR);
		icoCtxMenuAnd = new IcoCtxMenu(this, CTX_MENU_SADV_AND);
		fillContextMenus();
		setCbackCtxMenu(icoCtxMenuOr);
		setCbackCtxMenu(icoCtxMenuAnd);
		
		btn.setOnClickListener(btnClick);
		
		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
			  public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
				  if(pos==0)
					  return;
				  
				  TextView tv_help = (TextView) etGrp.findViewById(R.id.metatag_help);
				  if (tv_help.getVisibility() == TextView.GONE &&
						  etGrp.getChildCount() > 0)
					  tv_help.setVisibility(TextView.VISIBLE);
				  
				  //se non esiste già questo elemento
				  if(etGrp.findViewById(pos) == null){
					  createEt(pos,CTX_MENU_SADV_OR,null);
				  } else {
					  Toast.makeText(getApplicationContext(), 
						R.string.toast_sadv_already_term, Toast.LENGTH_SHORT)
					  		.show();
				  }

				  spinner.setSelection(0);
			  }

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {}
		});
		
        
		@SuppressWarnings("unchecked")
		HashMap<String,Object> state = (HashMap<String, Object>) getLastNonConfigurationInstance();
		
		if(state != null){
			loadData(state);	
		}
	}	

	private void createEt(int pos,int cong,String text){
		  EditText et = new EditText(getApplicationContext());
		  et.setLayoutParams(new LinearLayout.LayoutParams(
				  LayoutParams.MATCH_PARENT, 
				  LayoutParams.WRAP_CONTENT));

		  if(spinnkeyar[pos-1].equalsIgnoreCase(A_KEY_DATE))
			  et.setOnClickListener(etDatepicker);
		 
		  if(text!=null)
			  et.setText(text);
		  
		  et.setHint(spinner_label[pos]+": ");
		  et.setTag(cong);
		  et.setId(pos);
		  et.setOnLongClickListener(etLongClick);
		  et.setOnFocusChangeListener(etFocusChange);
		  etGrp.addView(et);
		  et.requestFocus();
	}
	
	@SuppressWarnings("unchecked")
	private void loadData(HashMap<String,Object> state) {
		gcong= (Integer) state.get("gcong");

		ArrayList<Boolean> s_media= (ArrayList<Boolean>) state.get("s_media");
		dir.setChecked(s_media.get(0));
		video.setChecked(s_media.get(1));
		audio.setChecked(s_media.get(2));
		
		ArrayList<Integer> eId= (ArrayList<Integer>) state.get("eId");
		ArrayList<Integer> eLcong= (ArrayList<Integer>) state.get("eLcong");
		ArrayList<String> eTxt= (ArrayList<String>) state.get("eTxt");
		for(int i=0;i<eId.size();i++){
			createEt(eId.get(i),eLcong.get(i),eTxt.get(i));
		}

	}
	
	private static void showDpDialog(View v){
		SMethod.closeSoftKeyboard(imm, v);
		DatePickerDialog DPD = new DatePickerDialog(
				activity, mDateSetListener, mYear, mMonth, mDay);
			
		DPD.show();
	}
	
	private OnClickListener etDatepicker = new OnClickListener() {
		@Override
		public void onClick(View v) {
			showDpDialog(v);
		}
	};	
	/**
	 * Tolgo e rimetto l'hint, senza questo in caso di più ET 
	 * non si riuscirebbe a distinguerle.
	 */
	private static OnFocusChangeListener etFocusChange = new OnFocusChangeListener() {
		@Override
		public void onFocusChange(View v, boolean hasFocus) {
			String txt  = ((EditText) v).getText().toString();
			
			if (txt.length()>0) {
				String hint = ((EditText) v).getHint().toString(), 
					new_txt = "";	
				
				if (hasFocus) 
					new_txt = txt.replace(hint, "");
				else 
					new_txt = hint + txt;
				
				if(new_txt.length()>0)
					((EditText) v).setText(new_txt);
			}
			
			if( hasFocus && spinnkeyar[v.getId()-1].equalsIgnoreCase(A_KEY_DATE) ){
				if (txt.length()>0) 
					SMethod.closeSoftKeyboard(imm, v);
				else
					showDpDialog(v);
			}
		}
	};
	
	private static DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
			mYear = year;
			mMonth = monthOfYear;
			mDay = dayOfMonth;

			EditText et = (EditText) activity.findViewById(SMethod.nameSearch(spinnkeyar, A_KEY_DATE)+1);
			et.setText(new StringBuilder()
				// Month is 0 based so add 1
				.append(mYear).append(A_DATE_SPLIT)	
				.append(mMonth + 1).append(A_DATE_SPLIT)
				.append(mDay));
		}
	};

	private static OnClickListener btnClick = new OnClickListener() {
		@Override
		public void onClick(View v) {
			int nViews=etGrp.getChildCount();
			String ret = "", glob_cong=A_CONG_AND;
			if(subMenu != null && subMenu.getItem(MENUCTX_ITEM_OR).isChecked())
				glob_cong=A_CONG_OR;
			
			for(int i=1; i<nViews;i++){
				String term="";
				EditText eChild = (EditText) etGrp.getChildAt(i);
				if(eChild != null){
					String txts = eChild.getText().toString();
					String txt[]=txts.split(",[\\s]*");
					int n_txt=txt.length;
					if( n_txt > 0 && txt[0].length() > 0) {
						term=spinnkeyar[eChild.getId()-1]+": ( ";
						
						String cong=A_CONG_OR;
						if((Integer) eChild.getTag()==CTX_MENU_SADV_AND)
							cong=A_CONG_AND;
						
						for(int t=0; t<n_txt;t++){
							String txt_no_hint=txt[t];
							if(t==0)
								txt_no_hint=txt_no_hint.replace((String) eChild.getHint(), "");
							term+="\""+txt_no_hint+"\" ";
							
							if(t!=n_txt-1)
								term+=cong+" ";
						}
						
						term+=") ";
					} 
				}
					
				if(i!=nViews-1)
					term+=glob_cong+" ";
					
				ret+=term;
				Log.d(LOG_TAG,"term:"+term);
			}	
			
			if( ret.length() > 2) {
				int n_media=0;
				if (dir.isChecked())
					n_media++;
				
				if(audio.isChecked())
					n_media+=2;
			
				if(video.isChecked())
					n_media+=4;
				
				if(n_media>0){
					String media_txt=A_CONG_AND+" "+A_KEY_MEDIAT+": ( ";
					switch (n_media) {
					case 1:
						media_txt += A_MEDIAT_DIR;
						break;
					case 2:
						media_txt += A_MEDIAT_AUDIO;
						break;
					case 4:
						media_txt += A_MEDIAT_VIDEO;
						break;	
					case 3:
						media_txt += A_MEDIAT_AUDIO+" "+A_CONG_OR+" "+A_MEDIAT_DIR;
						break;
					case 5:
						media_txt += A_MEDIAT_VIDEO+" "+A_CONG_OR+" "+A_MEDIAT_DIR;
						break;
					case 6:
						media_txt += A_MEDIAT_VIDEO+" "+A_CONG_OR+" "+A_MEDIAT_AUDIO;
						break;
					case 7:
						media_txt = "";
						break;
					}
					media_txt += " )";
						
					ret+=media_txt;
				}
			}

			Log.i(LOG_TAG,"query:"+ret);
			if( ret.equals("")){
				activity.setResult(RESULT_CANCELED);
			} else {
				Intent data = new Intent();
				data.putExtra("query_adv", ret);
				activity.setResult(RESULT_OK,data);					
			}
	
			activity.finish();
		}
	};
	
	/**
	 * MENU CONTESTUALE EFFETTUATO CON DIALOG 
	 */
	private void fillCommonContextMenuItems(IcoCtxMenu menu){
		menu.addItem(res, R.string.diag_act_svuota, R.drawable.svuota, MENUCTX_ITEM_VOID);
		menu.addItem(res, R.string.diag_act_delete, R.drawable.delete, MENUCTX_ITEM_DELETE);
	}
	
	private void fillContextMenus() {
		fillCommonContextMenuItems(icoCtxMenuOr);
		icoCtxMenuOr.addItem(res, R.string.diag_act_and, R.drawable.and, MENUCTX_ITEM_AND);
		
		fillCommonContextMenuItems(icoCtxMenuAnd);
		icoCtxMenuAnd.addItem(res, R.string.diag_act_or, R.drawable.or, MENUCTX_ITEM_OR);
	}
	
	private void setCbackCtxMenu(IcoCtxMenu menu) {
		menu.setOnClickListener(new IcoCtxMenu.IconContextMenuOnClickListener() {
			@Override
			public void onClick(int menuId) {
				if (itemLClicked != null){
					//Log.d(LOG_TAG,"setCbackCtxMenu:"+menuId);
					switch (menuId) {
					case MENUCTX_ITEM_AND:
						itemLClicked.setTag(CTX_MENU_SADV_AND);
						break;
					case MENUCTX_ITEM_OR:
						itemLClicked.setTag(CTX_MENU_SADV_OR);
						break;
					case MENUCTX_ITEM_DELETE:
						etGrp.removeView(itemLClicked);
						if (etGrp.getChildCount() == 1)
							tv_help.setVisibility(TextView.GONE);
						break;
					case MENUCTX_ITEM_VOID:
						((EditText) itemLClicked).setText("");
						break;
					}
				}
			}
		});
	}
	
	private static OnLongClickListener etLongClick = new OnLongClickListener() {
		@Override
		public boolean onLongClick(View v) {
			itemLClicked = v;
			activity.showDialog((Integer) v.getTag());
			return true;
		}
	};
	
	@Override
	protected Dialog onCreateDialog(int id) {
		//Log.d(LOG_TAG, "onCreateDialog():"+id+" OR:"+CTX_MENU_SADV_OR+" AND:"+CTX_MENU_SADV_AND);
		switch (id) {
		case CTX_MENU_SADV_AND:
			dialog = icoCtxMenuAnd.createMenu("Menu: ", R.drawable.ic_tab_search);
			break;
		case CTX_MENU_SADV_OR:
			dialog = icoCtxMenuOr.createMenu("Menu: ", R.drawable.ic_tab_search);
			break;
		case MENU_HELP_ID:
			dialog = SDialog.neutralDialog(this, id, R.string.diag_sadv_help_title, R.drawable.ic_menu_about, 
					SDialog.setHtmlTV(this, R.string.diag_sadv_help));
			break;
		case DIALOG_DATEPICKER:
			super.onPrepareDialog(id, dialog);
			((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
			break;
		}

		return  dialog;
	}
	/**
	 * MENU DELL'ACTIVITY 
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(Menu.CATEGORY_ALTERNATIVE, MENU_CLEANALL_ID, 0,
				R.string.menu_sadv_deleteall)
				.setOnMenuItemClickListener(menuItemClickHandler)
				.setIcon(R.drawable.delete);

        subMenu = 
           	menu.addSubMenu(Menu.CATEGORY_ALTERNATIVE, MENU_CONGEN_ID, 0, R.string.menu_sadv_congen)
        		.setIcon(R.drawable.cong)
        		.setHeaderIcon(R.drawable.cong)
        		.setHeaderTitle(R.string.submenu_sadv_congen);
        
        boolean and_cheched=true, or_cheched=false;
        if(gcong==MENUCTX_ITEM_OR){
        	and_cheched=false;
        	or_cheched=true;	
        }
        subMenu.add(0,MENUCTX_ITEM_AND,MENUCTX_ITEM_AND,R.string.diag_act_and)
        	.setOnMenuItemClickListener(menuItemClickHandler)
        	.setCheckable(true)
        	.setChecked(and_cheched);	
        subMenu.add(0,MENUCTX_ITEM_OR,MENUCTX_ITEM_OR,R.string.diag_act_or)
        	.setOnMenuItemClickListener(menuItemClickHandler)
        	.setCheckable(true)
        	.setChecked(or_cheched);
        	
		menu.add(Menu.CATEGORY_ALTERNATIVE, MENU_HELP_ID, 0,
				R.string.menu_sadv_help)
				.setOnMenuItemClickListener(menuItemClickHandler)
				.setIcon(R.drawable.ic_menu_about);
        
		return true;
	}

	private OnMenuItemClickListener menuItemClickHandler = new OnMenuItemClickListener() {
		@Override
		public boolean onMenuItemClick(MenuItem item) {
			int id = item.getItemId();
			switch (id) {
				case MENU_CLEANALL_ID :
					int nViews=etGrp.getChildCount();
					for(int i=1; i<nViews;i++)
						etGrp.removeViewAt(1);
					
					tv_help.setVisibility(TextView.GONE);
					break;
				case MENU_HELP_ID:
					showDialog(MENU_HELP_ID);
					break;
				case MENUCTX_ITEM_AND:
					subMenu.getItem(MENUCTX_ITEM_AND).setChecked(true);
					subMenu.getItem(MENUCTX_ITEM_OR).setChecked(false);
					break;
				case MENUCTX_ITEM_OR:
					subMenu.getItem(MENUCTX_ITEM_AND).setChecked(false);
					subMenu.getItem(MENUCTX_ITEM_OR).setChecked(true);
					break;
			}

			return true;
		}
	};
	
	@Override
    public Object onRetainNonConfigurationInstance() {
		Log.i(LOG_TAG,"onRNConfInstance()");
		HashMap<String, Object> state = new HashMap<String, Object>();
		
		ArrayList<Boolean> s_media = new ArrayList<Boolean>();
		s_media.add(0, false);
		if (dir.isChecked())
			s_media.set(0, true);
		s_media.add(1, false);
		if(video.isChecked())
			s_media.set(1, true);
		s_media.add(2, false);
		if(audio.isChecked())
			s_media.set(2, true);
		state.put("s_media", s_media);
		
		int gcong=MENUCTX_ITEM_AND;
		if(subMenu != null && subMenu.getItem(MENUCTX_ITEM_OR).isChecked())
			gcong=MENUCTX_ITEM_OR;
		state.put("gcong", gcong);

		ArrayList<Integer> eId = new ArrayList<Integer>();
		ArrayList<Integer> eLcong = new ArrayList<Integer>();
		ArrayList<String> eTxt = new ArrayList<String>();
		int nViews=etGrp.getChildCount();
		for(int i=1; i<nViews;i++){
			EditText eChild = (EditText) etGrp.getChildAt(i);
			if(eChild != null){
				String txt = eChild.getText().toString();
				eId.add(eChild.getId());
				eLcong.add((Integer) eChild.getTag());
				eTxt.add(txt.replace(eChild.getHint(), ""));
			}
		}	
		state.put("eId",eId);
		state.put("eLcong",eLcong);
		state.put("eTxt",eTxt);

        return state;
    }
}
