/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.cerner.tw.icmd.clin.assign.staff.unit.client;

import com.cerner.tw.icmd.clin.assign.staff.unit.client.rpc.GetRoomNames;
import com.cerner.tw.icmd.clin.assign.staff.unit.client.rpc.GetRoomNamesAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.fields.DataSourceImageField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.ListGridEditEvent;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.EventHandler;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.DropEvent;
import com.smartgwt.client.widgets.events.DropHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.events.TabCloseClickEvent;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;

/**
 *
 * @author JH019076
 */
public class UnitGridTab 
    extends Tab
{
    VLayout unitLayout;
    VLayout gridLayout;
    VLayout graphLayout;
    ListGrid unitGrid;
    ScheduleGraph schedule;
    Long roomId;
    String name;
    String[] startTimes;
    String[] endTimes;
    LinkedHashMap devices;
    DataSource currentDS = null;
    
    public UnitGridTab( String unitName, Long ID )
    {        
        unitLayout = new VLayout();
        gridLayout = new VLayout();
        graphLayout = new VLayout();
        unitGrid = new ListGrid();
        roomId = ID;
        name = unitName;

        setCanClose( new Boolean(true) );
        unitName = unitName.replace("'", "");
        unitName = unitName.replace(" ", "_");
        setTitle(unitName);
        setPickerTitle(name);
        setID(ID.toString());

        /*TODO add CLose handler
        addCloseClickHandler(new CloseClickHandler() {
            public void onCloseClick(TabCloseClickEvent event) {
               Tab tab = event.getTab();
               System.out.println("");
             }
         });*/

        currentDS = new DataSource();
        String id = new String( "currentStaff_"+roomId );
        currentDS.setID(id);
        currentDS.setDataFormat(DSDataFormat.JSON);
        currentDS.setDataURL("assignments?location_id=" + roomId + "&current=true&i=" + Math.random() );

        DataSourceImageField dIconField = new DataSourceImageField("iconName", " ");
        dIconField.setImageURLPrefix("icons/16/");
        dIconField.setWidth(30);
        DataSourceTextField dFirstNameField = new DataSourceTextField( UnitAssignmentModule.DSF_FIRST_NAME, "First Name" );
        DataSourceTextField dLastNameField = new DataSourceTextField( UnitAssignmentModule.DSF_LAST_NAME, "Last Name" );
        DataSourceIntegerField personIdField = new DataSourceIntegerField( UnitAssignmentModule.DSF_ICMD_ID, "Person Id" );
        DataSourceTextField droleField = new DataSourceTextField(UnitAssignmentModule.DSF_ROLE, "Role");
        DataSourceTextField dsAssignField = new DataSourceTextField (UnitAssignmentModule.DSF_ASSIGNMENT, "Assignments");
        DataSourceTextField dsShiftStartField = new DataSourceTextField (UnitAssignmentModule.DSF_SHIFT_START, "Shift Start");
        DataSourceTextField dsShiftStartEnd = new DataSourceTextField (UnitAssignmentModule.DSF_SHIFT_END, "ShiftEnd");
        droleField.setValueXPath("role");
        DataSourceTextField dsDeviceField = new DataSourceTextField( UnitAssignmentModule.DSF_DEVICE, "Device");
        personIdField.setHidden( new Boolean(true));
        personIdField.setPrimaryKey(new Boolean(true));
        personIdField.setRequired( new Boolean(true));
        currentDS.setClientOnly( new Boolean( false ) );
        currentDS.setFields( dIconField, dFirstNameField, dLastNameField, personIdField, droleField,
                dsAssignField, dsShiftStartField, dsShiftStartEnd, dsDeviceField );
        unitGrid.setDataSource(currentDS);

        unitGrid.setAutoFetchData( new Boolean( true ) );
        unitGrid.setAutoSaveEdits( new Boolean( true ) );
        unitGrid.fetchData();
        
        unitGrid.setBorder( "0px" );
        unitGrid.setID(unitName+"_Grid");
        unitGrid.setEditByCell( new Boolean(false) );
        //unitGrid.setCanEdit( new Boolean(true) );
        unitGrid.setEditEvent( ListGridEditEvent.CLICK );
        unitGrid.setSelectionType(SelectionStyle.SINGLE);
        unitGrid.setAutoFetchData( new Boolean(true) );
        unitGrid.setCanEdit( new Boolean(true) );

        ListGridField iconField = new ListGridField("iconName", " ");
        iconField.setType( ListGridFieldType.IMAGE );
        iconField.setImageURLPrefix( "icons/16/" );
        iconField.setImageURLSuffix( ".png" );
        iconField.setCanEdit( new Boolean(false) );

        ListGridField lastNameField = new ListGridField( UnitAssignmentModule.DSF_LAST_NAME, "Last Name");
        lastNameField.setCanEdit( new Boolean(false) );

        ListGridField firstNameField = new ListGridField( UnitAssignmentModule.DSF_FIRST_NAME, "First Name" );
        firstNameField.setCanEdit( new Boolean(false) );

        ListGridField assignmentField = new ListGridField( UnitAssignmentModule.DSF_ASSIGNMENT, "Assignments");
        assignmentField.setCanEdit( new Boolean(false) );

        ListGridField roleField = new ListGridField( UnitAssignmentModule.DSF_ROLE, "Role", 100 );
        roleField.setCanEdit( new Boolean(false) );

        ListGridField shiftStartField = new ListGridField( UnitAssignmentModule.DSF_SHIFT_START, "Shift Start");
        shiftStartField.setValueMap(startTimes);
        shiftStartField.setCanEdit( new Boolean(false) );

        ListGridField shiftEndField = new ListGridField( UnitAssignmentModule.DSF_SHIFT_END, "Shift End");
        shiftEndField.setValueMap(endTimes);
        shiftEndField.setCanEdit( new Boolean(false) );
        ListGridField deviceField = new ListGridField( UnitAssignmentModule.DSF_DEVICE, "Device", 150);
        deviceField.setValueMap( devices );
        deviceField.setCanEdit( new Boolean(false) );
        unitGrid.setFields(
            new ListGridField[]
            {
                iconField,
                firstNameField,
                lastNameField,
                assignmentField,
                roleField,
                shiftStartField, shiftEndField,
                deviceField
            } );
        unitGrid.setCanAcceptDroppedRecords( new Boolean( true ) );
        unitGrid.addDropHandler( new ActiveStaffDropHandler() );
        unitGrid.setHeight100();

        gridLayout.addMember(unitGrid);
        schedule = new ScheduleGraph(name, roomId);
        graphLayout.addMember(schedule);
        graphLayout.setHeight("50%");
        gridLayout.setHeight("50%");
        gridLayout.setOverflow(Overflow.AUTO);
        graphLayout.setOverflow(Overflow.AUTO);
        gridLayout.setShowResizeBar( new Boolean(true) );

        unitLayout.addMember(gridLayout);
        unitLayout.addMember(graphLayout);
        setPane(unitLayout);
        
    }

    public Long getRoomId()
    {
        return roomId;
    }

    public String getRoomName()
    {
        return name;
    }

    public void refresh()
    {
        unitGrid.endEditing();
        GetRoomNamesAsync roomNameService = (GetRoomNamesAsync) GWT.create(GetRoomNames.class);
        ((ServiceDefTarget) roomNameService).setServiceEntryPoint( GWT.getModuleBaseURL() + "roomNames");
        roomNameService.getTimeOptions(null, new AsyncCallback() {
                // This method will be called if the service call fails
                public void onFailure(Throwable caught) {
                    // Show a message informing the user why the call failed
                    com.google.gwt.user.client.Window.alert("Failed to get response from server: " + caught.getMessage());
                }

                // This method will be called if the service call succeeds
                public void onSuccess(Object result) {
                    // Get the service call result and cast it to the desired type and display it
                    endTimes = startTimes = (String []) result;

                    loadDeviceNamesAndRefresh (roomId);
                    
                }
         });
    }

    class ActiveStaffDropHandler
        implements DropHandler
    {
        public void onDrop( DropEvent event )
        {
            Canvas dragging = EventHandler.getDragTarget();

            if ( dragging instanceof ListGrid )
            {
                ListGrid lg = (ListGrid) dragging;
                ListGridRecord[] sel = lg.getSelection();
                ListGridRecord[] oldData = unitGrid.getRecords();

                HashSet<String> seen = new HashSet<String>();
                LinkedList<ListGridRecord> add = new LinkedList<ListGridRecord>();

                for ( int i=0; i<oldData.length; i++ )
                {
                    ListGridRecord myRec = oldData[i];
                    add.add( myRec );
                    String myId = myRec.getAttribute( UnitAssignmentModule.DSF_ICMD_ID );
                    seen.add( myId );
                }

                for ( int i=0; i<sel.length; i++ )
                {
                    ListGridRecord myRec = sel[i];
                    String myId = myRec.getAttribute( UnitAssignmentModule.DSF_ICMD_ID );

                    if ( ! seen.contains( myId ) )
                    {
                        add.add( myRec );
                        seen.add( myId );
                    }
                }

                unitGrid.setData( add.toArray( new ListGridRecord[0] ) );
                unitGrid.markForRedraw();
                event.cancel();
            }
            else
            {
                SC.say( "Dropped onto active list: "+dragging.getID()+"\n"+dragging.getClass().getName() );
            }
        }
    }

    private String [] loadTimeOptions (String startTime)
    {
        GetRoomNamesAsync roomNameService = (GetRoomNamesAsync) GWT.create(GetRoomNames.class);
        ((ServiceDefTarget) roomNameService).setServiceEntryPoint( GWT.getModuleBaseURL() + "roomNames");
        roomNameService.getTimeOptions(startTime, new AsyncCallback() {
                // This method will be called if the service call fails
                public void onFailure(Throwable caught) {
                    // Show a message informing the user why the call failed
                    com.google.gwt.user.client.Window.alert("Failed to get response from server: " + caught.getMessage());
                }

                // This method will be called if the service call succeeds
                public void onSuccess(Object result) {
                    // Get the service call result and cast it to the desired type and display it
                   String [] stringArray = (String []) result;
                   //com.google.gwt.user.client.Window.alert("Failed to get response from server: " + stringArray.length);
                }
         });
        return null;
    }

    public LinkedHashMap loadDeviceNamesAndRefresh ( Long locId )
    {
        // get a list of device names based on the default
        // destination profile for the given location
        GetRoomNamesAsync roomNameService = (GetRoomNamesAsync) GWT.create(GetRoomNames.class);
        ((ServiceDefTarget) roomNameService).setServiceEntryPoint( GWT.getModuleBaseURL() + "roomNames");
        roomNameService.getDeviceNames(locId, new AsyncCallback() {
                // This method will be called if the service call fails
                public void onFailure(Throwable caught) {
                    // Show a message informing the user why the call failed
                    com.google.gwt.user.client.Window.alert("Failed to get response from server: " + caught.getMessage());
                }

                // This method will be called if the service call succeeds
                public void onSuccess(Object result) {
                    // Get the service call result and cast it to the desired type and display it
                   devices = (LinkedHashMap) result;

                   /*
                   currentDS.setDataURL("assignments?location_id=" + roomId + "&current=true&i=" + (new Date ()).getTime() );
                   com.google.gwt.user.client.Window.alert(currentDS.getDataURL());
                   unitGrid.setDataSource(currentDS);
                    */

                   // TODO: FIX THIS TO SHOW SECONDARY ASSIGNMENTS TOO
                    ListGridField iconField = new ListGridField("iconName", " ");
                    iconField.setType( ListGridFieldType.IMAGE );
                    iconField.setImageURLPrefix( "icons/16/" );
                    iconField.setImageURLSuffix( ".png" );
                    iconField.setCanEdit( new Boolean(false) );

                    ListGridField firstNameField = new ListGridField( UnitAssignmentModule.DSF_FIRST_NAME, "First Name");
                    firstNameField.setCanEdit( new Boolean(false) );
                    ListGridField lastNameField = new ListGridField( UnitAssignmentModule.DSF_LAST_NAME, "Last Name");
                    lastNameField.setCanEdit( new Boolean(false) );

                    ListGridField roleField = new ListGridField( UnitAssignmentModule.DSF_ROLE, "Role", 100);
                    roleField.setCanEdit( new Boolean(false) );

                    ListGridField assignmentField = new ListGridField(UnitAssignmentModule.DSF_ASSIGNMENT,"Assignments");
                    assignmentField.setCanEdit( new Boolean(false) );
                    java.util.Date today = new java.util.Date();

                    ListGridField shiftStartField = new ListGridField(UnitAssignmentModule.DSF_SHIFT_START,"Shift Start");
                    shiftStartField.setValueMap(startTimes);
                    shiftStartField.setCanEdit( new Boolean(false) );
                    ListGridField shiftEndField = new ListGridField(UnitAssignmentModule.DSF_SHIFT_END, "Shift End");
                    shiftEndField.setValueMap(endTimes);
                    shiftEndField.setCanEdit( new Boolean(false) );
                    ListGridField deviceField = new ListGridField(UnitAssignmentModule.DSF_DEVICE,"Device", 150);
                    deviceField.setValueMap( devices );
                    deviceField.setCanEdit( new Boolean(false) );
                    unitGrid.setFields(
                        new ListGridField[]
                        {
                            iconField,
                            lastNameField,
                            firstNameField,
                            assignmentField,
                            roleField,
                            shiftStartField, shiftEndField,
                            deviceField
                        } );

                    unitGrid.invalidateCache();
                    unitGrid.fetchData();

                    graphLayout.removeMember(schedule);
                    schedule = new ScheduleGraph(name, roomId);
                    graphLayout.addMember(schedule);
                    graphLayout.markForRedraw();
                    unitGrid.markForRedraw(); 
                }
         });
        return devices;
    }

    public void stopEditing()
    {
        unitGrid.endEditing();
    }

}
