package eu.dnetlib.client.widgets;


import java.util.ArrayList;

import com.github.gwtbootstrap.client.ui.Image;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.TextDecoration;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import eu.dnetlib.shared.FiltersData;

public class AutoCompleteWidget implements IsWidget{

	private FlowPanel masterPanel = new FlowPanel();
	private FlowPanel suggestionList = new FlowPanel();
	public TextBox inputTextBox = new TextBox();
	private static String BASE_URL = "http://dl114.madgik.di.uoa.gr/stats/";
	private FiltersData filtersData;
    private Timer timer;
    private String table = new String();
    private String field = new String();
	private String valueSelected = null;
	private HTML loadingWheel = new HTML("<div class=\"loader-big\"></div><div class=\"whiteFilm\"></div>");
	private Label loadingLabel = new Label();
	private ArrayList<String> blacklist = new ArrayList<String>();
	
	public interface SearchingListener{
		public void onSearch();
		public void onReturn();
	}
	
	private SearchingListener searchingListener;
	
	public void setSearchingListener(SearchingListener searchingListener){
		this.searchingListener = searchingListener;
	}
	
	public interface AddingListener{
		public void onEvent(String value);
	}
	
	public TextBox getInputTextBox() {
		return inputTextBox;
	}

	public void setInputTextBox(TextBox inputTextBox) {
		this.inputTextBox = inputTextBox;
	}
	private AddingListener addingListener;
	
	public void setAddingListener(AddingListener addingListener){
		this.addingListener=addingListener;
	}
	
    public interface DeleteListener{
    	public void onEvent();
    }
    
	public String getTable() {
		return table;
	}

	public void setTable(String table) {
		this.table = table;
	}

	public String getField() {
		return field;
	}

	public void setField(String field) {
		this.field = field;
	}
	
	public String getValueSelected(){
		return this.valueSelected;
	}

	public AutoCompleteWidget(String type, String placeholder,String table, String field,ArrayList<String> blacklist) {
		
		this.blacklist = blacklist;
		this.table = table;
		this.field = field;
		masterPanel.addStyleName("autoCompleteWidget");
		masterPanel.add(inputTextBox);
		loadingLabel.setText("Loading..");
		loadingLabel.addStyleName("suggestionInfoItemLoading");
		inputTextBox.addStyleName("filterTextBox");
		inputTextBox.getElement().setAttribute("placeholder", placeholder);
		this.inputTextBox.setFocus(true);
		inputTextBox.addKeyUpHandler(new KeyUpHandler() {

			@Override
			public void onKeyUp(KeyUpEvent event) {
				if(timer==null) {

                    timer = new Timer() {

                        @Override
                        public void run() {
                            bringRecommendations();
                        }
                    };
                    timer.schedule(1000);

                } else {

                    timer.cancel();
                    timer = new Timer() {

                        @Override
                        public void run() {
                            bringRecommendations();
                        }
                    };
                    timer.schedule(1000);
                }
			}
		});
	}
	
	public void bringRecommendations(){
		if(!inputTextBox.getText().equals("")){
			suggestionList.clear();
			masterPanel.add(suggestionList);
			suggestionList.addStyleName("suggestionList");
			
			Image tempImage = new Image("./loading_background.gif");
			tempImage.addStyleName("loading-image-suggestion");
			
			suggestionList.add(loadingLabel);
			suggestionList.add(tempImage);
			
			AjaxRequest(BASE_URL + "ajaxRouter9.php?com=filterData&table="+this.table+"&field="+this.field+"&input="+inputTextBox.getText());
			if(searchingListener!=null){
				searchingListener.onSearch();
			}
		}else
			masterPanel.remove(AutoCompleteWidget.this.suggestionList);
	}
	
	private void AjaxRequest (final String URL){
		

		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL);
	
		try {
			
			
			Request request = builder.sendRequest(null, new RequestCallback() {
				
				@Override
				public void onResponseReceived(Request request, Response response) {
					
	
					if(response.getStatusCode()==200){
						suggestionList.clear();
						filtersData = JsonUtils.safeEval(response.getText().toString());
						if(filtersData.getData()!=null && filtersData.getData().length()!=0){
							for(int i=0;i<filtersData.getData().length();i++){
								final Anchor anchor = new Anchor();
								anchor.setText(filtersData.getData().get(i).toString());
								anchor.addStyleName("suggestionItem");
								anchor.getElement().setId(filtersData.getData().get(i).toString());
								anchor.addClickHandler(new ClickHandler() {
									
									@Override
									public void onClick(ClickEvent event) {
										inputTextBox.setValue(anchor.getText());
										inputTextBox.setText(anchor.getText());
										inputTextBox.setEnabled(false);
										masterPanel.remove(AutoCompleteWidget.this.suggestionList);
										valueSelected=anchor.getText();
										if(addingListener!=null){
											addingListener.onEvent(anchor.getText());	
										}
									}
								});
								boolean found=false;
								for(int j=0;j<blacklist.size();j++){
									if(blacklist.get(j).equals(filtersData.getData().get(i).toString())){
										anchor.getElement().getStyle().setTextDecoration(TextDecoration.LINE_THROUGH);
										found=true;
										break;
									}
									
								}
								if(found){
									anchor.getElement().getStyle().setTextDecoration(TextDecoration.LINE_THROUGH);
									anchor.setText(anchor.getText()+"(added)");
									anchor.getElement().getStyle().setProperty("pointer-events", "none");
								}else{
									blacklist.add(filtersData.getData().get(i).toString());
								}
								suggestionList.add(anchor);
								
							}
						}else{
							Label label = new Label("No result found");
							label.addStyleName("suggestionInfoItem");
							suggestionList.add(label);
						}
						if(searchingListener!=null){
							searchingListener.onReturn();
						}
						suggestionList.addStyleName("suggestionList");
						masterPanel.remove(AutoCompleteWidget.this.suggestionList);
						masterPanel.add(suggestionList);
						AutoCompleteWidget.this.suggestionList = suggestionList;
					}else{
						DisplayError("Could not retrieve JSON");
					}
				}
				
				@Override
				public void onError(Request request, Throwable exception) {
					DisplayError("Could not retrieve JSON2 ");
				}
			});
		} catch (RequestException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			DisplayError("Could not retrieve JSON3");
		}
	}
	
	
	public void DisplayError(String msg){
		Window.alert(msg);
		
	}
	@Override
	public Widget asWidget() {
		return masterPanel;
	}

    public void addStyleName(String styleName) {
        masterPanel.addStyleName(styleName);
    }
}
