/*
 * HistoryPresenter.java
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */
package org.rstudio.studio.client.workbench.views.vcs.dialog;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.inject.Inject;
import org.rstudio.core.client.Invalidation;
import org.rstudio.core.client.Invalidation.Token;
import org.rstudio.core.client.TimeBufferedCommand;
import org.rstudio.studio.client.common.SimpleRequestCallback;
import org.rstudio.studio.client.common.vcs.VCSServerOperations;
import org.rstudio.studio.client.workbench.views.vcs.diff.UnifiedParser;
import org.rstudio.studio.client.workbench.views.vcs.events.SwitchViewEvent;

import java.util.ArrayList;

public class HistoryPresenter
{
   public interface Display extends IsWidget
   {
      void setData(ArrayList<CommitInfo> commits);

      HasClickHandlers getSwitchViewButton();
      CommitListDisplay getCommitList();
      CommitDetailDisplay getCommitDetail();

      HasClickHandlers getRefreshButton();

      HasData<CommitInfo> getDataDisplay();

      HasValue<String> getFilterTextBox();
   }

   public interface CommitListDisplay
   {
      HandlerRegistration addSelectionChangeHandler(
            SelectionChangeEvent.Handler handler);

      CommitInfo getSelectedCommit();
   }

   public interface CommitDetailDisplay
   {
      void setSelectedCommit(CommitInfo commit);
      void clearDetails();
      void setDetails(UnifiedParser unifiedParser);
   }

   @Inject
   public HistoryPresenter(VCSServerOperations server,
                           final Display view,
                           HistoryAsyncDataProvider provider)
   {
      server_ = server;
      view_ = view;
      provider_ = provider;

      view_.getCommitList().addSelectionChangeHandler(new SelectionChangeEvent.Handler()
      {
         @Override
         public void onSelectionChange(SelectionChangeEvent event)
         {
            CommitInfo commitInfo = view_.getCommitList().getSelectedCommit();
            view_.getCommitDetail().setSelectedCommit(commitInfo);
            view_.getCommitDetail().clearDetails();
            invalidation_.invalidate();

            if (commitInfo == null)
               return;

            final Token token = invalidation_.getInvalidationToken();

            server_.vcsShow(commitInfo.getId(),
                            new SimpleRequestCallback<String>()
                            {
                               @Override
                               public void onResponseReceived(String response)
                               {
                                  super.onResponseReceived(response);
                                  if (token.isInvalid())
                                     return;

                                  UnifiedParser parser = new UnifiedParser(
                                        response);
                                  view_.getCommitDetail().setDetails(parser);
                               }
                            });
         }
      });

      view_.getRefreshButton().addClickHandler(new ClickHandler()
      {
         @Override
         public void onClick(ClickEvent event)
         {
            refreshHistory();
         }
      });

      provider_.setFilter(view_.getFilterTextBox());
      view_.getFilterTextBox().addValueChangeHandler(new ValueChangeHandler<String>()
      {
         @Override
         public void onValueChange(ValueChangeEvent<String> stringValueChangeEvent)
         {
            refreshHistoryCommand_.nudge();
         }
      });
   }

   private void refreshHistory()
   {
      provider_.refreshCount();
      provider_.onRangeChanged(view_.getDataDisplay());
   }

   public HandlerRegistration addSwitchViewHandler(
         final SwitchViewEvent.Handler h)
   {
      return view_.getSwitchViewButton().addClickHandler(new ClickHandler()
      {
         @Override
         public void onClick(ClickEvent event)
         {
            h.onSwitchView(new SwitchViewEvent());
         }
      });
   }


   public Widget asWidget()
   {
      return view_.asWidget();
   }

   public void onShow()
   {
      if (!initialized_)
      {
         initialized_ = true;
         provider_.addDataDisplay(view_.getDataDisplay());
         provider_.refreshCount();
      }
   }

   private final TimeBufferedCommand refreshHistoryCommand_ = new TimeBufferedCommand(1000)
   {
      @Override
      protected void performAction(boolean shouldSchedulePassive)
      {
         refreshHistory();
      }
   };

   private final VCSServerOperations server_;
   private final Display view_;
   private final HistoryAsyncDataProvider provider_;
   private final Invalidation invalidation_ = new Invalidation();
   private boolean initialized_;
}

@@ -1539,16 +1539,325 @@
 ewEvent;
+%0Aimport org.rstudio.studio.client.workbench.views.vcs.events.VcsRefreshEvent;%0Aimport org.rstudio.studio.client.workbench.views.vcs.events.VcsRefreshEvent.Reason;%0Aimport org.rstudio.studio.client.workbench.views.vcs.events.VcsRefreshHandler;%0Aimport org.rstudio.studio.client.workbench.views.vcs.model.VcsState;
 %0A%0Aimport
@@ -2828,16 +2828,62 @@
 provider
+,%0A                           VcsState vcsState
 )%0A   %7B%0A 
@@ -4802,24 +4802,307 @@
  %7D%0A      %7D);
+%0A%0A      vcsState.bindRefreshHandler(view.asWidget(), new VcsRefreshHandler()%0A      %7B%0A         @Override%0A         public void onVcsRefresh(VcsRefreshEvent event)%0A         %7B%0A            if (event.getReason() == Reason.VcsOperation)%0A               refreshHistory();%0A         %7D%0A      %7D);
 %0A   %7D%0A%0A   pr

Refresh history on VCS operation (switch branch)