package org.arkiwi.app.activity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import org.arkiwi.app.R;
import org.arkiwi.app.adapter.AdapterExpandList;
import org.arkiwi.app.interfaces.Define;
import org.arkiwi.app.interfaces.RssInterface;
import org.arkiwi.app.rss.RssDoc;
import org.arkiwi.app.rss.RssQueryTask;
import org.arkiwi.app.rss.RssReader;
import org.arkiwi.app.utility.SMethod;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodManager;

public class Search extends Activity implements OnClickListener, Define{
	private final static String LOG_TAG = "AASearch";
	private final static int EXP_SUGGEST_GRP = 0;
	private final static int EXP_TEMP_GRP = 1;
	
	private static RssQueryTask task;
	private static RssDoc rssDocs;
	
	private ArrayList<String> groups;
	private ArrayList<ArrayList<ArrayList<String>>> childs;
	private HashMap<String, String> words;

	private static Resources res;
	
	private static ExpandableListView expView;
	private AdapterExpandList expListAdapter;
	private static Button searchBtn;
	private static EditText searchBox;
	private static TextView searchAdv;
	private static Intent sAdvIntent;

	private InputMethodManager imm;
	
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.search_main);
        //Log.i(LOG_TAG,"onCreate()");
        res = getResources();
		searchBox = (EditText) findViewById(R.id.searchBox);
        searchBtn = (Button) findViewById(R.id.searchButton);
        searchAdv = (TextView) findViewById(R.id.adv_search_act);
        expView = (ExpandableListView) findViewById(R.id.ExpListViewSearched);
        imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        sAdvIntent = new Intent(this,SearchAdv.class);
        
		@SuppressWarnings("unchecked")
		HashMap<String,Object> state = (HashMap<String, Object>) getLastNonConfigurationInstance();

        loadData(state);
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
    	//Log.i(LOG_TAG,"onResume()");
    	
    	rssDocs = RssDoc.getInstance(ATab.max_cache);
    	
        expListAdapter = new AdapterExpandList(this, groups, childs);
        expView.setAdapter(expListAdapter);
        
        //espande la lista delle ricerche se ne sono state fatte
        if (! SMethod.arrayListToString(childs.get(EXP_TEMP_GRP).get(0))
        		.equalsIgnoreCase(res.getString(R.string.search_no_ricerche)))
        	expView.expandGroup(EXP_TEMP_GRP);
        
        //cambia il testo nel box cerca a seconda della vecchia ricerca sulla quale è avvenuto il click 
		expView.setOnChildClickListener(new OnChildClickListener() {
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				Boolean ret=false;
				
				String childLabel=SMethod.arrayListToString(childs.get(groupPosition).get(childPosition));
				if (! childLabel.equalsIgnoreCase(getString(R.string.search_no_ricerche))) {
					doSearch(childLabel, words.get(childLabel));
					ret = true;
				}
				
				return ret;
			}
		});
		//pressione dell'invio scatena l'evento on click sul bottone search
		searchBox.setOnKeyListener(new OnKeyListener() {
		    public boolean onKey(View v, int keyCode, KeyEvent event) {
		    	//Log.d(LOG_TAG, "onKey()");
		        if (event.getAction() == KeyEvent.ACTION_DOWN)
		        {
		            switch (keyCode)
		            {	
		            	//pressione del trackpad e del tasto invio del softkeyboard
		                case KeyEvent.KEYCODE_DPAD_CENTER:
		                case KeyEvent.KEYCODE_ENTER:
		                    searchBtn.performClick();
		                    return true;
		                default:
		                    break;
		            }
		        }

		        return false;
		    }
		});

		searchAdv.setOnClickListener(this);
		searchBtn.setOnClickListener(this); 
    }
    
	private void startTask(String uri){
		task = new RssQueryTask(this, "search");
		task.execute(uri);
	}
	
    private void setViewTmpSearch(String aquery){
    	SMethod.closeSoftKeyboard(imm,searchBox);
    	
		boolean already=false;
		
    	int nextPos = childs.get(EXP_TEMP_GRP).size();
    	//se è la prima ricerca, sostituisci il msg di benvenuto
    	if(nextPos == 1 && 
    		getString(R.string.search_no_ricerche)
    		.equalsIgnoreCase(SMethod.arrayListToString(
    				childs.get(EXP_TEMP_GRP).get(0)))){

    		nextPos = 0;
    		childs.get(EXP_TEMP_GRP).remove(nextPos);
    		expView.expandGroup(EXP_TEMP_GRP);
    	}
    	
    	if (! expView.isGroupExpanded(EXP_TEMP_GRP))
    		expView.expandGroup(EXP_TEMP_GRP);
    	
   		for (int i=0;i<nextPos;i++) {
   			if(aquery.equalsIgnoreCase(
   					SMethod.arrayListToString(childs.get(EXP_TEMP_GRP).get(i)))){
   				already = true;
   				break;
   			}
   		}
    	
    	if(! already) {
    		//inserisce la nuova ricerca
    		childs.get(EXP_TEMP_GRP).add(new ArrayList<String>());
    		childs.get(EXP_TEMP_GRP).get(nextPos).add(aquery);
    		//refresh delle vecchie ricerche anche quando il menù è espanso
    		expListAdapter.notifyDataSetChanged();
    	}
    }
    
    public void doSearch(String s, String toSearch){
		String how = A_SEARCH_64;
		String[] search_def = res.getStringArray(R.array.search_def);
		if(! ( s.equalsIgnoreCase(res.getString(R.string.search_def_video)) ||
			s.equalsIgnoreCase(res.getString(R.string.search_def_audio)))){
			if(Arrays.asList(search_def).contains(s)){
				how = A_SEARCH_PATH;
			}
    	}
		String uri = A_TARGET_URL + how + toSearch + A_RSS_VIEW;

		if(RssReader.getFromState()==RssReader.STATE_BACK_VIEWER)
			RssReader.setFromState(RssReader.STATE_INIT_VIEWER);
		
		/*
		 * tree è lo stack di visualizzazioni nella griglia in Viewer,
		 * viene purgata ad ogni nuova ricerca.
		 */
		rssDocs.treeClear();
		rssDocs.treePushElement(uri);
		//inserisco la stringa cercata nella lista 
		setViewTmpSearch(s);
		//Cerco nella cache
		int n = RssInterface.HTTP_UNSETTED;		
		String xml = rssDocs.getDocFromCache(uri);
		RssDoc.resetNBackPress();
		if(! xml.equalsIgnoreCase("")) {
			n = rssDocs.setRss(xml,false);
			Log.d(LOG_TAG, "doSearch() "+ n);
			if (n > 0){
				ATab.tabHost.setCurrentTab(1);
			}
		} 
		// Cerco su arkiwi
		if (n == 0 || n == RssInterface.XML_PAGLIAIO_DOWN || n == RssInterface.HTTP_UNSETTED ){
			startTask(uri);
		}
    }
    /**
     * Recupera da arkiwi o dalla cache al click del bottone 
     * la ricerca inserita nel'input box
     */
	public void onClick(View arg0) {
		if (arg0 == searchBtn) {
			if(searchBox.getText().length() > 1){
				Log.i("main" +":", "onClick searchBtn");
				String s = searchBox.getText().toString();
				String toSearch;
				if(words.containsKey(s)) {
					toSearch = words.get(s);
				} else {
					String rfc4648 = s.replace('+', '-').replace('/', '_');
					toSearch = Base64.encodeToString(rfc4648.getBytes(), Base64.NO_WRAP | Base64.NO_PADDING);
					words.put(s, toSearch);
				}
				
				doSearch(s, toSearch);
			} else {
				Toast.makeText( getApplicationContext(), 
						R.string.toast_less1_search, Toast.LENGTH_LONG).show();
			}
		} else if(arg0 == searchAdv){
			//TODO: hardcoded 0 - search
			startActivityForResult(sAdvIntent, 0);
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.i(LOG_TAG,"rq:"+requestCode+" rc:"+resultCode);
        if (resultCode == RESULT_OK) {
    		Bundle bundle = data.getExtras();
            String query = bundle.getString("query_adv");
            
            searchBox.setText(query);
        }		
	}

    @Override
	public void onBackPressed() {  
		RssReader.setFromState(RssReader.STATE_BACK_VIEWER);
		super.onBackPressed();
		
	    return;  
	}  
	
    @Override
    protected void onPause() {
    	super.onPause();
    	SMethod.closeSoftKeyboard(imm,searchBox);
    	
    	Bundle bundle = new Bundle();
    	bundle.putBoolean("first", true);
    	onSaveInstanceState(bundle);
		//Log.i(LOG_TAG,"onPause()");
    }

	@Override
    public Object onRetainNonConfigurationInstance() {
		Log.i(LOG_TAG,"onRetainNonConfigurationInstance()");
		HashMap<String, Object> state = new HashMap<String, Object>();
		state.put("words", words);
		state.put("searched", childs.get(EXP_TEMP_GRP));

        return state;
    }
	
    @Override
    protected void onStop() {
    	//Log.i(LOG_TAG,"onStop()");
    	super.onStop();
    	if(task!=null){
    		task.cancel(true);
    	}
    }
    
	private void loadData(HashMap<String,Object> state){
    	if (state != null) {
    		words=(HashMap<String, String>) state.get("words");
    	} else {
    		words=new HashMap<String, String>();
    	}
    	
    	groups= new ArrayList<String>();
    	childs= new ArrayList<ArrayList<ArrayList<String>>>();

		//Setto le ricerche comuni
		groups.add(getString(R.string.search_group_common));
		childs.add(new ArrayList<ArrayList<String>>());

		String[] search_def = res.getStringArray(R.array.search_def);
		String[] search_def_search = res.getStringArray(R.array.search_def_search);
		for(int i=0;i<search_def.length;i++){
			childs.get(EXP_SUGGEST_GRP).add(new ArrayList<String>());
	        childs.get(EXP_SUGGEST_GRP).get(i).add(search_def[i]);
	        words.put(search_def[i], search_def_search[i]);
		}
		
		//Ricarico o setto le ricerche temporanee
    	groups.add(getString(R.string.search_group_old));
        childs.add(new ArrayList<ArrayList<String>>());
        if (state != null) {
        	@SuppressWarnings("unchecked")
			ArrayList<ArrayList<String>> c =  (ArrayList<ArrayList<String>>) state.get("searched");
        	for (int i=0; i<c.size();i++){
        		childs.get(EXP_TEMP_GRP).add(new ArrayList<String>());
        		childs.get(EXP_TEMP_GRP).get(i).add(c.get(i).get(0));
        	}
        }else{
        	childs.get(EXP_TEMP_GRP).add(new ArrayList<String>());
    		childs.get(EXP_TEMP_GRP).get(0).add(getString(R.string.search_no_ricerche));
        }
    }
}