/*
 * ICESOFT COMMERCIAL SOURCE CODE LICENSE V 1.1
 *
 * The contents of this file are subject to the ICEsoft Commercial Source
 * Code License Agreement V1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the
 * License at
 * http://www.icesoft.com/license/commercial-source-v1.1.html
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * Copyright 2009-2015 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 */
package com.icesoft.faces.facelets.example.richdatagrid;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.faces.convert.DateTimeConverter;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

import com.icesoft.faces.application.showcase.model.entity.Employee;
import com.icesoft.faces.application.showcase.model.service.EmployeeService;
import com.icesoft.faces.application.showcase.view.bean.examples.component.dataTable.DataTableBase;
import com.icesoft.faces.context.effects.Effect;
import com.icesoft.faces.context.effects.Highlight;
import com.icesoft.faces.facelets.component.table.editable.EditableTableException;
import com.icesoft.faces.facelets.component.table.editable.IEditableTableEventListener;
import com.icesoft.faces.facelets.component.table.richdatagrid.BaseRichDataColumn;
import com.icesoft.faces.facelets.component.table.richdatagrid.RichDataBooleanRowProperty;
import com.icesoft.faces.facelets.component.table.richdatagrid.RichDataDateColumn;
import com.icesoft.faces.facelets.component.table.richdatagrid.RichDataGridBean;
import com.icesoft.faces.facelets.component.table.richdatagrid.RichDataListColumn;
import com.icesoft.faces.facelets.component.table.richdatagrid.RichDataTextColumn;

public class RichDataGridExampleBean extends DataTableBase {

   private RichDataGridBean richDataGridBean;
   private RichDataGridBean richDataGridBean2;
   private String richDataGridBeanEventMessage;
   private Effect richDataGridBeanEventMessageEffect;
   private boolean readOnly1;
   private boolean readOnly2;
   
   private int newRowIndex;
   private String newRowLocation;
   private int existingRowId;
   private boolean confirmDelete = true;

   public boolean isReadOnly1() {
      return readOnly1;
   }

   public void setReadOnly1(boolean readOnly1) {
      this.readOnly1 = readOnly1;
   }

   public boolean isReadOnly2() {
      return readOnly2;
   }

   public void setReadOnly2(boolean readOnly2) {
      this.readOnly2 = readOnly2;
   }
   
   public RichDataGridBean getRichDataGridBean2() {
      return richDataGridBean2;
   }

   private List<SelectItem> departments;

   public RichDataGridExampleBean() {
   }

   public String getRichDataGridBeanEventMessage() {
      return richDataGridBeanEventMessage;
   }

   public Effect getRichDataGridBeanEventMessageEffect() {
      return richDataGridBeanEventMessageEffect;
   }

   public void initializeRichDataGrids() {

      BaseRichDataColumn[] columns = new BaseRichDataColumn[5];
      columns[0] = new RichDataTextColumn(Integer.class, "id", "ID", false,
            false, true, true, false, false);
      columns[0].setTitleProperty("lastName");
      columns[0].setWidth("50px");
      columns[1] = new RichDataTextColumn(String.class, "firstName",
            "First Name", true, true, true, false, true);
      columns[2] = new RichDataTextColumn(String.class, "lastName",
            "Last Name", true, true, true, true, true);
      columns[3] = new RichDataListColumn("departmentName", "Department", true,
            true, false, true, "#{richDataGridExampleBean.departments}");
      DateTimeConverter dateTimeConverter = new DateTimeConverter();
      dateTimeConverter.setDateStyle("default");
      columns[4] = new RichDataDateColumn("birthDate", "Birth Date", true,
            true, false, true, dateTimeConverter);
      RichDataBooleanRowProperty editableRowProperty = new RichDataBooleanRowProperty(
            Employee.class, "editable");
      richDataGridBean = new RichDataGridBean(getEmployees(), columns,
            editableRowProperty, new MyTableEventListener());

      richDataGridBean2 = new RichDataGridBean(getEmployees());
      richDataGridBean2.setEditableRowProperty(editableRowProperty);
   }

   public void setEmployeeService(EmployeeService employeeService) {
      super.setEmployeeService(employeeService);
      initializeRichDataGrids();
   }

   public RichDataGridBean getRichDataGridBean() {
      return richDataGridBean;
   }

   public List<SelectItem> getDepartments() {
      if (departments == null) {
         departments = new ArrayList<SelectItem>();
         Set<String> departmentSet = new HashSet<String>();
         for (Employee emp : this.getEmployees()) {
            departmentSet.add(emp.getDepartmentName());
         }
         for (String dep : departmentSet) {
            departments.add(new SelectItem(dep));
         }
      }
      return departments;
   }

   private void fireRichDataGridBeanEventMessageEffect() {
      richDataGridBeanEventMessageEffect = new Highlight();
      richDataGridBeanEventMessageEffect.setDuration(4f);
   }

   private class MyTableEventListener implements IEditableTableEventListener,
         Serializable {

      public Object createNewRow() {
         Employee emp = new Employee();
         emp.setBirthDate(new Date());
         emp.setId(460 + richDataGridBean.getData().getRowCount());
         emp.setDepartmentName("Central");
         richDataGridBeanEventMessage = "A new row was created";
         fireRichDataGridBeanEventMessageEffect();
         return emp;
      }

      public void rowDeleted(Object row) {
         richDataGridBeanEventMessage = "A row was deleted: " + row;
         fireRichDataGridBeanEventMessageEffect();
      }

      public void rowSelected(Object row) {
         richDataGridBeanEventMessage = "A row was selected: " + row;
         fireRichDataGridBeanEventMessageEffect();
      }

      public void rowUpdated(Object oldBean, Object newBean) {
         richDataGridBeanEventMessage = "A row was updated from : " + oldBean
               + " to " + newBean;
         fireRichDataGridBeanEventMessageEffect();
      }

      public void rowEditCanceled(Object oldBean, Object newBean)
            throws EditableTableException {
         richDataGridBeanEventMessage = "A row edit was canceled: " + oldBean
               + " to " + newBean;
         fireRichDataGridBeanEventMessageEffect();
      }

   }

    public int getNewRowIndex() {
        return newRowIndex;
    }
    
    public void setNewRowIndex(int newRowIndex) {
        this.newRowIndex = newRowIndex;
    }
    
    public String getNewRowLocation() {
        return newRowLocation;
    }
    
    public void setNewRowLocation(String newRowLocation) {
        this.newRowLocation = newRowLocation;
    }
    
    public void addNewRowAboveOrBelowExistingId(ActionEvent evt){
        Object row = null;
        Iterator<Employee> iter = ((List<Employee>)richDataGridBean.getData()
                .getWrappedData()).iterator();
        while( iter.hasNext() ){
            Employee e = iter.next();
            if( e.getId() == existingRowId){
                row = e;
                break;
            }
        }
        if( row != null){
            this.richDataGridBean.createNewRow(row, newRowLocation);
        }
        else{
            System.out.println("RichDataGridBean.addNewRowAboveOrBelowExistingId() no row selected");
        }
        
    }
    
    public void addNewRowAtIndex(ActionEvent evt){
        this.richDataGridBean.createNewRowAtIndex(newRowIndex);
    }

    public int getExistingRowId() {
        return existingRowId;
    }

    public void setExistingRowId(int existingRowId) {
        this.existingRowId = existingRowId;
    }

    public boolean isConfirmDelete() {
        return confirmDelete;
    }

    public void setConfirmDelete(boolean confirmDelete) {
        this.confirmDelete = confirmDelete;
    }


}
