package org.drools.guvnor.client.mvp;

import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.ui.IsWidget;
import org.drools.guvnor.client.workbench.WorkbenchPart;
import org.drools.guvnor.client.workbench.widgets.events.ActivityCloseEvent;
import org.drools.guvnor.client.workbench.widgets.events.ActivityCloseHandler;
import org.drools.guvnor.client.workbench.widgets.events.WorkbenchPartHideEvent;
import org.drools.guvnor.client.workbench.widgets.events.WorkbenchPartHideHandler;
import org.drools.guvnor.client.workbench.widgets.panels.PanelManager;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;

@ApplicationScoped
public class PlaceManagerImpl
        implements
        PlaceManager {

    private final Map<IPlaceRequest, Activity>           activeActivities       = new HashMap<IPlaceRequest, Activity>();
    private final Map<IPlaceRequest, WorkbenchPart>      existingWorkbenchParts = new HashMap<IPlaceRequest, WorkbenchPart>();

    @Inject
    private ActivityMapper                               activityMapper;

    @Inject
    private PlaceRequestHistoryMapper                    historyMapper;

    @Inject
    private com.google.web.bindery.event.shared.EventBus eventBus;

    private PlaceHistoryHandler                          placeHistoryHandler;

    IPlaceRequest                                        currentPlaceRequest;

    @PostConstruct
    public void init() {
        placeHistoryHandler = new PlaceHistoryHandler( historyMapper );
        placeHistoryHandler.register( this,
                                      eventBus,
                                      new PlaceRequest( "NOWHERE" ) );
    }

    @Override
    public void goTo(IPlaceRequest placeRequest) {
        currentPlaceRequest = placeRequest;
        revealPlace( placeRequest );
    }

    @Override
    public IPlaceRequest getCurrentPlaceRequest() {
        if ( currentPlaceRequest != null ) {
            return currentPlaceRequest;
        } else {
            return new PlaceRequest( "NOWHERE" );
        }
    }

    private void revealPlace(final IPlaceRequest newPlace) {
        final Activity activity = activityMapper.getActivity( newPlace );

        activeActivities.put( newPlace,
                              activity );

        activity.revealPlace(
                new AcceptItem() {
                    public void add(String tabTitle,
                                    IsWidget widget) {

                        WorkbenchPart workbenchPart = new WorkbenchPart( widget.asWidget(),
                                                                         tabTitle );

                        existingWorkbenchParts.put( newPlace,
                                                    workbenchPart );

                        workbenchPart.addActivityCloseHandler(
                                new ActivityCloseHandler() {
                                    @Override
                                    public void onCloseActivity(ActivityCloseEvent event) {
                                        onClosePlace( new ClosePlaceEvent( newPlace ) );
                                    }
                                } );

                        workbenchPart.addWorkbenchPartHideHandler( new WorkbenchPartHideHandler() {
                            @Override
                            public void onHide(WorkbenchPartHideEvent event) {
                                activity.hide();
                            }
                        } );

                        workbenchPart.addSelectionHandler( new SelectionHandler<WorkbenchPart>() {
                            @Override
                            public void onSelection(SelectionEvent<WorkbenchPart> workbenchPartSelectionEvent) {
                                activity.show();
                            }
                        } );

                        PanelManager.getInstance().addWorkbenchPanel( workbenchPart,
                                                                      activity.getPreferredPosition() );
                    }
                } );
        updateHistory( newPlace );
    }

    public void updateHistory(IPlaceRequest request) {
        placeHistoryHandler.onPlaceChange( request );
    }

    public void onClosePlace(@Observes ClosePlaceEvent closePlaceEvent) {
        final Activity activity = activeActivities.get( closePlaceEvent.getPlaceRequest() );
        if ( activity.mayClosePlace() ) {
            activity.closePlace();
            activeActivities.remove( activity );
            existingWorkbenchParts.remove( closePlaceEvent.getPlaceRequest() ).close();
        }
    }

}

@@ -2337,24 +2337,393 @@
 newPlace) %7B%0A
+%0A        //If we're already showing this place exit.%0A        //TODO What should we do if the Activity is hidden? Hidden Activities do not appear to%0A        //be handled in PlaceManagerImpl. Are hidden Activities still stored here, or do we need%0A        //some other mechanism?!?!%0A        if ( activeActivities.containsKey( newPlace ) ) %7B%0A            return;%0A        %7D%0A%0A
         fina
@@ -2780,25 +2780,24 @@
 newPlace );%0A
-%0A
         acti
@@ -4920,32 +4920,103 @@
 sePlaceEvent) %7B%0A
+        final IPlaceRequest place = closePlaceEvent.getPlaceRequest();%0A
         final Ac
@@ -5059,41 +5059,13 @@
 et( 
-closePlaceEvent.getPlaceRequest()
+place
  );%0A
@@ -5178,24 +5178,21 @@
 remove( 
-activity
+place
  );%0A    
@@ -5234,41 +5234,13 @@
 ve( 
-closePlaceEvent.getPlaceRequest()
+place
  ).c

Fix issues reported by Jervis:- - Opening the same asset (Path) in multiple windows - Closing last of multiple (single-instance) windows->RTE