package org.gcube.portlets.user.workspace.client.view.grids;

import java.util.Arrays;
import java.util.List;

import org.gcube.portlets.user.workspace.client.AppController;
import org.gcube.portlets.user.workspace.client.ConstantsExplorer;
import org.gcube.portlets.user.workspace.client.event.DoubleClickElementSelectedEvent;
import org.gcube.portlets.user.workspace.client.event.FileDownloadEvent;
import org.gcube.portlets.user.workspace.client.event.FileDownloadEvent.DownloadType;
import org.gcube.portlets.user.workspace.client.event.GridElementSelectedEvent;
import org.gcube.portlets.user.workspace.client.event.GridElementUnSelectedEvent;
import org.gcube.portlets.user.workspace.client.event.ImagePreviewEvent;
import org.gcube.portlets.user.workspace.client.event.OpenContextMenuTreeEvent;
import org.gcube.portlets.user.workspace.client.event.OpenReportsEvent;
import org.gcube.portlets.user.workspace.client.interfaces.GXTFolderItemTypeEnum;
import org.gcube.portlets.user.workspace.client.model.FileGridModel;
import org.gcube.portlets.user.workspace.client.model.FileModel;
import org.gcube.portlets.user.workspace.client.model.GroupingStoreModel;

import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.grid.filters.DateFilter;
import com.extjs.gxt.ui.client.widget.grid.filters.GridFilters;
import com.extjs.gxt.ui.client.widget.grid.filters.NumericFilter;
import com.extjs.gxt.ui.client.widget.grid.filters.StringFilter;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.i18n.client.NumberFormat;

/**
 * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
 *
 */
public class GxtGridFilterGroupPanel extends LayoutContainer {

	private ContentPanel cp = new ContentPanel();
//	private ListStore<FileModel> store =  ListStoreModel.getInstance().getStore();
	private GroupingStore<FileGridModel> store = GroupingStoreModel.getInstance().getStore();
	private FileGridModel currenItemSelected = null;
	private FileModel currentFolderView = null;
	private final NumberFormat number = NumberFormat.getFormat("#,##0 KB;(#,##0 KB)");
	private GroupingView view = new GroupingView();
	private boolean groupingEnabled = false;  

	public GxtGridFilterGroupPanel(boolean group) {
		setLayout(new FitLayout());
		ColumnConfig icon = new ColumnConfig(ConstantsExplorer.ICON, "", 25);
		ColumnConfig name = new ColumnConfig(ConstantsExplorer.NAME, ConstantsExplorer.NAME, 300);
		ColumnConfig type = new ColumnConfig(ConstantsExplorer.TYPE, ConstantsExplorer.TYPE, 100);
		ColumnConfig creationDate = new ColumnConfig(ConstantsExplorer.GRIDCOLUMNCREATIONDATE, ConstantsExplorer.GRIDCOLUMNCREATIONDATE, 100);
		ColumnConfig category = new ColumnConfig(ConstantsExplorer.SHORTCUTCATEGORY, ConstantsExplorer.SHORTCUTCATEGORY, 100);
		ColumnConfig size = new ColumnConfig(ConstantsExplorer.SIZE, ConstantsExplorer.SIZE, 50);
		
		size.setEditor(new CellEditor(new NumberField()));   
		
		ColumnModel cm  = null;
		
		if(group)
			cm = new ColumnModel(Arrays.asList(icon, name, type, creationDate, size, category));
		else
			cm = new ColumnModel(Arrays.asList(icon, name, type, creationDate, size));
			
		final ColumnModel columnModel = cm;
		
		cp.setBodyBorder(true);
//		cp.setHeading(ConstantsPortlet.RESULT);
		cp.setHeaderVisible(false);
		cp.setLayout(new FitLayout());

		final Grid<FileGridModel> grid = new Grid<FileGridModel>(store, columnModel);
		grid.getView().setAutoFill(true);
		grid.setBorders(true);
		
		
	    view.setShowGroupedColumn(false);  
	    view.setForceFit(true); 
	 	grid.setView(view);
	    view.setEmptyText(ConstantsExplorer.EMPTY);
	    
//	    view.setGroupRenderer(new GridGroupRenderer() {  
//	      public String render(GroupColumnData data) {  
//	        String f = columnModel.getColumnById(data.field).getHeader();  
//	        String l = data.models.size() == 1 ? "Item" : "Items";  
//	        return f + ": " + data.group + " (" + data.models.size() + " " + l + ")";  
//	      }  
//	    });  
		
	    if(group){
	    	store.groupBy(ConstantsExplorer.SHORTCUTCATEGORY);
	    	groupingEnabled = true;
	    }
	    
	    GridCellRenderer<FileGridModel> folderRender = new GridCellRenderer<FileGridModel>() {  
			@Override
			public String render(FileGridModel model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<FileGridModel> store, Grid<FileGridModel> grid) {
		          String val = model.get(property);  
		          String color = "black";
		          
		          if(val != null && val.equals(GXTFolderItemTypeEnum.FOLDER.toString())){
//		        	  color = "#EEC900";
		        	  return "<span qtitle='" + columnModel.getColumnById(property).getHeader() + "' qtip='" + val  + "' style='font-weight: bold;color:" + color + "'>" + val + "</span>";
		          }else{
		        	  if(val==null)
		        		  val = "";
		        	  return "<span qtitle='" + columnModel.getColumnById(property).getHeader() + "' qtip='" + val  + "' style='color:" + color + "'>" + val + "</span>";
		          }
			}  
	      };  
	      
	      GridCellRenderer<FileGridModel> kbRender = new GridCellRenderer<FileGridModel>() {
	      @Override
	      public String render(FileGridModel model, String property, ColumnData config,
		      int rowIndex, int colIndex, ListStore<FileGridModel> store, Grid<FileGridModel> grid) {
	    	  
	    	  long value = (Long) model.get(property);
	    	  
	    	  if(value!=-1){
	    		  String color = "black";
	//		      int val = Integer.parseInt(value);
	//			      String style = (val/1024) < 2000000 ? "red" : "green";
			      double kb = value/1024;
			      if(kb<1)
			    	  kb=1;
			      return "<span style='color:"+color+"'>" + number.format(kb) + "</span>";
		      
	    	  }
	    	  
	    	  return "";
	      	}
	      };

	    size.setRenderer(kbRender);
	    type.setRenderer(folderRender);
	
	    //setAlphanumericStoreSorter(grid);
	
		GridFilters filters = new GridFilters();
		filters.setLocal(true);
	
		StringFilter nameFilter = new StringFilter(ConstantsExplorer.NAME);
		StringFilter authorFilter = new StringFilter(ConstantsExplorer.TYPE);
		DateFilter dateFilter = new DateFilter(ConstantsExplorer.GRIDCOLUMNCREATIONDATE);
		NumericFilter sizeFilter = new NumericFilter(ConstantsExplorer.SIZE);
		

		filters.addFilter(nameFilter);
		filters.addFilter(authorFilter);
		filters.addFilter(dateFilter);
		filters.addFilter(sizeFilter);
		
		// grid.setStyleAttribute("borderTop", "none");
		grid.setAutoExpandColumn(ConstantsExplorer.NAME);
		grid.setBorders(false);
		grid.setStripeRows(true);
		grid.setColumnLines(true);
		
		grid.getView().setShowDirtyCells(false);
		
	//		grid.setSize(500, 500);
		grid.addPlugin(filters);
		
		grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
		
		grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<FileGridModel>() {
			
			@Override
			public void selectionChanged(SelectionChangedEvent<FileGridModel> se) {
				System.out.println("selection grid change");
				
				ModelData target = se.getSelectedItem();
				
				if(target!=null){
					currenItemSelected = (FileGridModel) target;
					AppController.getEventBus().fireEvent(new GridElementSelectedEvent(target));
				}
				else{
					currenItemSelected = null;
					AppController.getEventBus().fireEvent(new GridElementUnSelectedEvent());
				}
			}
		});
	
		
		grid.addListener(Events.RowDoubleClick, new Listener<BaseEvent>() {
	
			@Override
			public void handleEvent(BaseEvent be) {
				
				FileGridModel fileModel = grid.getSelectionModel().getSelectedItem();
				
				if(fileModel!=null)
					fireEventByFileModelType(fileModel);
	//				if(fileModel.isDirectory())
	//					AppController.getEventBus().fireEvent(new DoubleClickElementSelectedEvent(fileModel));
			}
	        
	    });
		
		
		grid.setContextMenu(null); //add context menu null - ignore browse event right click 
		
		grid.addListener(Events.OnContextMenu, new Listener<GridEvent<FileGridModel>>(){
			@Override
			public void handleEvent(GridEvent<FileGridModel> be) 
			{
	
		   		if(be.isRightClick())
		   		{
		   			if(grid.getSelectionModel().getSelectedItem()!=null){
		   				
		   				FileGridModel fileGridModel = grid.getSelectionModel().getSelectedItem();
		   				AppController.getEventBus().fireEvent(new OpenContextMenuTreeEvent(fileGridModel, be.getClientX(), be.getClientY()));
		   			}
		   		}
			}
		});
	
		cp.add(grid);
		add(cp);
	}
	
	public void disableGrouping() {
		GroupingStore<FileGridModel> groupingStore = null;
		if (this.getStore() instanceof GroupingStore) {
			groupingStore = (GroupingStore<FileGridModel>) this.getStore();
			if (groupingStore != null) {
				groupingStore.clearGrouping();
			}
			this.groupingEnabled = false;
		}
	}

	public void enableGrouping() {
		GroupingStore<FileGridModel> groupingStore = null;
		if (this.getStore() instanceof GroupingStore) {
			groupingStore = (GroupingStore<FileGridModel>) this.getStore();
			if (groupingStore != null) {
				groupingStore.groupBy(ConstantsExplorer.SHORTCUTCATEGORY);
			}
			this.groupingEnabled  = true;
		}
	}
	
	private void fireEventByFileModelType(FileModel target){
		
		if(target.isDirectory()){
			AppController.getEventBus().fireEvent(new DoubleClickElementSelectedEvent(target));
			return;
		}
		
		
		switch(target.getGXTFolderItemType()){
		
		case EXTERNAL_IMAGE: 
			AppController.getEventBus().fireEvent(new ImagePreviewEvent(target, 0, 0));
			break;
		case EXTERNAL_FILE: 
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case EXTERNAL_PDF_FILE: 
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case EXTERNAL_URL: 
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case REPORT_TEMPLATE: 
			AppController.getEventBus().fireEvent(new OpenReportsEvent(target));
			break;
		case REPORT: 
			AppController.getEventBus().fireEvent(new OpenReportsEvent(target));
			break;
		case QUERY: 
			break;
		case TIME_SERIES: 
			break;
		case PDF_DOCUMENT:
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case IMAGE_DOCUMENT: 
			AppController.getEventBus().fireEvent(new ImagePreviewEvent(target,0, 0));
			break;
		case DOCUMENT: 
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case URL_DOCUMENT:
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		case METADATA: 
			break;
		case WORKFLOW_REPORT: 
			break;
		case WORKFLOW_TEMPLATE: 
			break;
		case EXTERNAL_RESOURCE_LINK: 
			AppController.getEventBus().fireEvent(new FileDownloadEvent(target.getIdentifier(), target.getName(), DownloadType.SHOW));
			break;
		default:
		
		}
		
	}
	

	private void resetStore(){
		store.removeAll();
	}
	
	
	public boolean updateStore(List<FileGridModel> result){
		
		resetStore();
		if(result!= null){
			for(FileGridModel file: result)
				file.setIcon();
			store.add(result);
			return true;
		}
		return false;
	}
	
	public FileGridModel getSelectedItem(){
		
		return currenItemSelected;
		
	}
	
	/**
	 * 
	 * @param identifier (MANDATORY)
	 * @return
	 */
	public boolean deleteItem(String identifier) {
		
		FileGridModel fileTarget =  getFileGridModelByIdentifier(identifier);
		
		if(fileTarget!=null){
			Record record = store.getRecord(fileTarget); 
			store.remove((FileGridModel) record.getModel());
			return true;
		}
		else
			System.out.println("Delete Error: file target with " + identifier + " identifier not exist in store" );
		
		return false;
	}

	/**
	 * 
	 * @param fileTarget (MANDATORY)
	 * @param newName  (MANDATORY)
	 * @param extension OPTIONAL - string or null
	 */
	private boolean renameItem(FileGridModel fileTarget, String newName, String extension) {
		
		if(fileTarget!=null){
			Record record = store.getRecord(fileTarget); 
			if(record!=null){
				if(extension!= null)
					record.set(ConstantsExplorer.NAME, newName+extension);
				else
					record.set(ConstantsExplorer.NAME, newName);
				
				return true;
			}
			else
				System.out.println("Record Error: file target with " + fileTarget.getIdentifier() + " identifier not exist in store" );
		}
		else
			System.out.println("Rename Error: file target with is null" );
		
		return false;
	}


	public FileModel getCurrentFolderView() {
		return currentFolderView;
	}


	public void setCurrentFolderView(FileModel currentFolderView) {
		this.currentFolderView = currentFolderView;
	}


	public boolean renameItem(String itemIdentifier, String newName, String extension) {

		if(itemIdentifier!=null){
			FileGridModel fileTarget =  getFileGridModelByIdentifier(itemIdentifier);
			if(fileTarget!=null){
				Record record = store.getRecord(fileTarget);
				if(record!=null){
					if(extension!= null)
						record.set(ConstantsExplorer.NAME, newName+extension);
					else
						record.set(ConstantsExplorer.NAME, newName);
					
					return true;
				}
			}
			else
				System.out.println("Record Error: file target not exist in store" );
		}
		else
			System.out.println("Rename Error: file target is null" );
		
		return false;
		
	}
	
	public FileGridModel getFileGridModelByIdentifier(String id){
		return (FileGridModel) store.findModel(ConstantsExplorer.IDENTIFIER, id);	
	}
	
	public GroupingStore<FileGridModel> getStore(){
		return store;
	}
	
	public void setBorderAsOnSearch(boolean bool){
		
		if(this.cp.getElement("body")!=null){
			
			if(bool){
				this.cp.getElement("body").getStyle().setBorderColor("#32CD32");
			}
			else
				this.cp.getElement("body").getStyle().setBorderColor("#99BBE8");
		
		}
	}
	
}