// Copyright (C) 2010 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.client.changes;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.reviewdb.AccountGeneralPreferences;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwtexpui.globalkey.client.GlobalKey;
import com.google.gwtexpui.globalkey.client.KeyCommand;
import com.google.gwtexpui.globalkey.client.KeyCommandSet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Composite that displays the patch sets of a change. This composite ensures
 * that keyboard navigation to each changed file in all patch sets is possible.
 */
public class PatchSetsBlock extends Composite {

  private final Map<PatchSet.Id, PatchSetComplexDisclosurePanel> patchSetPanels =
      new HashMap<PatchSet.Id, PatchSetComplexDisclosurePanel>();

  private final ChangeScreen parent;
  private final FlowPanel body;
  private HandlerRegistration regNavigation;

  private List<PatchSetComplexDisclosurePanel> patchSetPanelsList;

  /**
   * the patch set id of the patch set for which is the keyboard navigation is
   * currently enabled
   */
  private PatchSet.Id activePatchSetId;

  /** the patch set id of the current (latest) patch set */
  private PatchSet.Id currentPatchSetId;

  /** Patch sets on this change, in order. */
  private List<PatchSet> patchSets;

  PatchSetsBlock(final ChangeScreen parent) {
    this.parent = parent;
    body = new FlowPanel();
    initWidget(body);
  }

  /** Adds UI elements for each patch set of the given change to this composite. */
  public void display(final ChangeDetail detail, final PatchSet.Id diffBaseId) {
    clear();

    final PatchSet currps = detail.getCurrentPatchSet();
    currentPatchSetId = currps.getId();
    patchSets = detail.getPatchSets();

    final List<PatchSet.Id> changePatchSets = new ArrayList<PatchSet.Id>();

    for (final PatchSet ps : patchSets) {
      changePatchSets.add(ps.getId());
    }

    if (Gerrit.isSignedIn()) {
      final AccountGeneralPreferences p =
          Gerrit.getUserAccount().getGeneralPreferences();
      if (p.isDisplayPatchSetsInReverseOrder()) {
        Collections.reverse(patchSets);
      }
    }

    patchSetPanelsList = new ArrayList<PatchSetComplexDisclosurePanel>();

    for (final PatchSet ps : patchSets) {
      final PatchSetComplexDisclosurePanel p;
      if (ps == currps) {
        p = new PatchSetComplexDisclosurePanel(parent, detail, detail
            .getCurrentPatchSetDetail());
        if (diffBaseId != null) {
          p.setDiffBaseId(diffBaseId);
          p.refresh();
        }
      } else {
        p = new PatchSetComplexDisclosurePanel(parent, detail, ps);
        if (diffBaseId != null) {
          p.setDiffBaseId(diffBaseId);
        }
      }
      add(p);
      patchSetPanelsList.add(p);
    }
  }

  private void clear() {
    setRegisterKeys(false);
    body.clear();
    patchSetPanels.clear();
  }

  public void refresh(final PatchSet.Id diffBaseId) {
    if (patchSetPanelsList != null) {
      for (final PatchSetComplexDisclosurePanel p : patchSetPanelsList) {
        p.setDiffBaseId(diffBaseId);
        if (p.isOpen()) {
          p.refresh();
        }
      }
    }
  }

  /**
   * Adds the given patch set panel to this composite and ensures that handler
   * to activate / deactivate keyboard navigation for the patch set panel are
   * registered.
   */
  private void add(final PatchSetComplexDisclosurePanel patchSetPanel) {
    body.add(patchSetPanel);

    final PatchSet.Id id = patchSetPanel.getPatchSet().getId();
    ActivationHandler activationHandler = new ActivationHandler(id);
    patchSetPanel.addOpenHandler(activationHandler);
    patchSetPanel.addClickHandler(activationHandler);
    patchSetPanels.put(id, patchSetPanel);
  }

  public void setRegisterKeys(final boolean on) {
    if (on) {
      KeyCommandSet keysNavigation =
          new KeyCommandSet(Gerrit.C.sectionNavigation());
      keysNavigation.add(new PreviousPatchSetKeyCommand(0, 'p', Util.C
          .previousPatchSet()));
      keysNavigation.add(new NextPatchSetKeyCommand(0, 'n', Util.C
          .nextPatchSet()));
      regNavigation = GlobalKey.add(this, keysNavigation);
      if (activePatchSetId != null) {
        activate(activePatchSetId);
      } else {
        activate(currentPatchSetId);
      }
    } else {
      if (regNavigation != null) {
        regNavigation.removeHandler();
        regNavigation = null;
      }
      deactivate();
    }
  }

  @Override
  protected void onUnload() {
    setRegisterKeys(false);
    super.onUnload();
  }

  /**
   * Activates keyboard navigation for the patch set panel that displays the
   * patch set with the given patch set id.
   * The keyboard navigation for the previously active patch set panel is
   * automatically deactivated.
   * This method also ensures that the current row is only highlighted in the
   * table of the active patch set panel.
   */
  public void activate(final PatchSet.Id patchSetId) {
    if (indexOf(patchSetId) != -1) {
      if (!patchSetId.equals(activePatchSetId)) {
        deactivate();
        PatchSetComplexDisclosurePanel patchSetPanel =
            patchSetPanels.get(patchSetId);
        patchSetPanel.setOpen(true);
        patchSetPanel.setActive(true);
        activePatchSetId = patchSetId;
      }
    } else {
      Gerrit.display(PageLinks.toChange(patchSetId.getParentKey()));
    }
  }

  /** Deactivates the keyboard navigation for the currently active patch set panel. */
  private void deactivate() {
    if (activePatchSetId != null) {
      PatchSetComplexDisclosurePanel patchSetPanel =
          patchSetPanels.get(activePatchSetId);
      patchSetPanel.setActive(false);
      activePatchSetId = null;
    }
  }

  public PatchSet getCurrentPatchSet() {
    PatchSetComplexDisclosurePanel patchSetPanel =
        patchSetPanels.get(currentPatchSetId);
    if (patchSetPanel != null) {
      return patchSetPanel.getPatchSet();
    } else {
      return null;
    }
  }

  private int indexOf(PatchSet.Id id) {
    for (int i = 0; i < patchSets.size(); i++) {
      if (patchSets.get(i).getId().equals(id)) {
        return i;
      }
    }
    return -1;
  }

  private class ActivationHandler implements OpenHandler<DisclosurePanel>,
      ClickHandler {

    private final PatchSet.Id patchSetId;

    ActivationHandler(PatchSet.Id patchSetId) {
      this.patchSetId = patchSetId;
    }

    @Override
    public void onOpen(OpenEvent<DisclosurePanel> event) {
      // when a patch set panel is opened by the user
      // it should automatically become active
      activate(patchSetId);
    }

    @Override
    public void onClick(ClickEvent event) {
      // when a user clicks on a patch table the corresponding
      // patch set panel should automatically become active
      activate(patchSetId);
    }

  }

  public class PreviousPatchSetKeyCommand extends KeyCommand {
    public PreviousPatchSetKeyCommand(int mask, char key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      int index = indexOf(activePatchSetId) - 1;
      if (0 <= index) {
        activate(patchSets.get(index).getId());
      }
    }
  }

  public class NextPatchSetKeyCommand extends KeyCommand {
    public NextPatchSetKeyCommand(int mask, char key, String help) {
      super(mask, key, help);
    }

    @Override
    public void onKeyPress(final KeyPressEvent event) {
      int index = indexOf(activePatchSetId) + 1;
      if (index < patchSets.size()) {
        activate(patchSets.get(index).getId());
      }
    }
  }
}
