// Copyright (C) 2008 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.patches;

import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.data.SideBySidePatchDetail;
import com.google.gerrit.client.reviewdb.Patch;
import com.google.gerrit.client.reviewdb.PatchSet;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NoDifferencesException;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.FancyFlexTable;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import com.google.gwtjsonrpc.client.RemoteJsonException;

import java.util.ArrayList;
import java.util.List;

public class PatchSideBySideScreen extends PatchScreen {
  private DisclosurePanel historyPanel;
  private HistoryTable historyTable;
  private FlowPanel sbsPanel;
  private SideBySideTable sbsTable;

  public PatchSideBySideScreen(final Patch.Key id) {
    super(id);
  }

  @Override
  public void onLoad() {
    if (sbsTable == null) {
      initUI();
    }

    super.onLoad();

    PatchUtil.DETAIL_SVC.sideBySidePatchDetail(patchId, null,
        new ScreenLoadCallback<SideBySidePatchDetail>() {
          public void onSuccess(final SideBySidePatchDetail r) {
            // TODO Actually we want to cancel the RPC if detached.
            if (isAttached()) {
              display(r);
            }
          }
        });
  }

  private void initUI() {
    historyTable = new HistoryTable();
    historyPanel = new DisclosurePanel(PatchUtil.C.patchHistoryTitle());
    historyPanel.setContent(historyTable);
    historyPanel.setVisible(false);
    add(historyPanel);

    sbsPanel = new FlowPanel();
    sbsPanel.setStyleName("gerrit-SideBySideScreen-SideBySideTable");
    sbsTable = new SideBySideTable();
    sbsPanel.add(sbsTable);
    add(sbsPanel);
  }

  private void display(final SideBySidePatchDetail detail) {
    showSideBySide(detail);
    if (detail.getHistory() != null && detail.getHistory().size() > 1) {
      historyTable.display(detail.getHistory());
      historyPanel.setOpen(false);
      historyPanel.setVisible(true);
    } else {
      historyPanel.setVisible(false);
    }
  }

  private void showSideBySide(final SideBySidePatchDetail r) {
    sbsTable.setAccountInfoCache(r.getAccounts());
    sbsTable.display(r);
    sbsTable.finishDisplay(true);
  }

  private class HistoryTable extends FancyFlexTable<Patch> {
    final List<HistoryRadio> all = new ArrayList<HistoryRadio>();

    HistoryTable() {
      table.addStyleName("gerrit-PatchHistoryTable");
      table.addTableListener(new TableListener() {
        public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
          if (row > 0) {
            movePointerTo(row);
          }
        }
      });
    }

    @Override
    protected Object getRowItemKey(final Patch item) {
      return item.getKey();
    }

    @Override
    protected boolean onKeyPress(final char keyCode, final int modifiers) {
      if (super.onKeyPress(keyCode, modifiers)) {
        return true;
      }
      if (modifiers == 0 && getCurrentRow() > 0) {
        switch (keyCode) {
          case 'o':
          case 'l': {
            final Widget w = table.getWidget(getCurrentRow(), radioCell(0));
            if (w != null) {
              fakeClick((HistoryRadio) w);
            }
            break;
          }

          case 'r':
          case 'n': {
            final int fileCnt = sbsTable.getFileCount();
            final Widget w =
                table.getWidget(getCurrentRow(), radioCell(fileCnt - 1));
            if (w != null) {
              fakeClick((HistoryRadio) w);
            }
            break;
          }
        }
      }
      return false;
    }

    private void fakeClick(final HistoryRadio b) {
      if (!b.isChecked() && b.isEnabled()) {
        for (final HistoryRadio a : all) {
          if (a.isChecked() && a.getName().equals(b.getName())) {
            a.setChecked(false);
            break;
          }
        }
        b.setChecked(true);
        onClick(b);
      }
    }

    public void onClick(final HistoryRadio b) {
      sbsTable.setVersion(b.file, b.patchSetId);
      boolean diff = false;
      PatchSet.Id last = sbsTable.getVersion(0);
      for (int i = 1; i < sbsTable.getFileCount(); i++) {
        if (!last.equals(sbsTable.getVersion(i))) {
          diff = true;
        }
      }

      enable(false);
      PatchUtil.DETAIL_SVC.sideBySidePatchDetail(patchId, sbsTable
          .getVersions(), new GerritCallback<SideBySidePatchDetail>() {
        public void onSuccess(final SideBySidePatchDetail r) {
          enable(true);
          sbsPanel.setVisible(true);
          showSideBySide(r);
        }

        @Override
        public void onFailure(final Throwable caught) {
          enable(true);
          if (isNoDifferences(caught)) {
            sbsPanel.setVisible(false);
          } else {
            super.onFailure(caught);
          }
        }

        boolean isNoDifferences(final Throwable caught) {
          if (caught instanceof NoDifferencesException) {
            return true;
          }
          return caught instanceof RemoteJsonException
              && caught.getMessage().equals(NoDifferencesException.MESSAGE);
        }
      });
    }

    private void enable(final boolean on) {
      for (final HistoryRadio a : all) {
        a.setEnabled(on);
      }
    }

    void display(final List<Patch> result) {
      all.clear();

      final SafeHtmlBuilder nc = new SafeHtmlBuilder();
      appendHeader(nc);
      for (int p = result.size() - 1; p >= 0; p--) {
        final Patch k = result.get(p);
        appendRow(nc, k);
      }
      appendRow(nc, null);
      resetHtml(nc);

      final int fileCnt = sbsTable.getFileCount();
      int row = 1;
      for (int p = result.size() - 1; p >= 0; p--, row++) {
        final Patch k = result.get(p);
        setRowItem(row, k);
        for (int file = 0; file < fileCnt; file++) {
          final PatchSet.Id psid = k.getKey().getParentKey();
          final HistoryRadio b = new HistoryRadio(psid, file);
          b.setChecked(psid.equals(sbsTable.getVersion(file)));
          installRadio(row, file, b);
        }
      }
      for (int file = 0; file < fileCnt - 1; file++) {
        setRowItem(row, new Patch(new Patch.Key(PatchSet.BASE, "")));
        final HistoryRadio b = new HistoryRadio(PatchSet.BASE, file);
        b.setChecked(b.patchSetId.equals(sbsTable.getVersion(file)));
        installRadio(row, file, b);
      }
    }

    private void installRadio(final int row, final int file,
        final HistoryRadio b) {
      final int cell = radioCell(file);
      table.setWidget(row, cell, b);
      table.getCellFormatter().setHorizontalAlignment(row, cell,
          HasHorizontalAlignment.ALIGN_CENTER);
      all.add(b);
    }

    private int radioCell(final int file) {
      return 2 + file;
    }

    private void appendHeader(final SafeHtmlBuilder m) {
      m.openTr();

      m.openTd();
      m.addStyleName(S_ICON_HEADER);
      m.addStyleName("LeftMostCell");
      m.nbsp();
      m.closeTd();

      m.openTd();
      m.setStyleName(S_DATA_HEADER);
      m.nbsp();
      m.closeTd();

      for (int file = 0; file < sbsTable.getFileCount(); file++) {
        m.openTd();
        m.setStyleName(S_DATA_HEADER);
        m.append(sbsTable.getFileTitle(file));
        m.closeTd();
      }

      m.openTd();
      m.setStyleName(S_DATA_HEADER);
      m.append(Util.C.patchTableColumnComments());
      m.closeTd();

      m.closeTr();
    }

    private void appendRow(final SafeHtmlBuilder m, final Patch k) {
      m.openTr();

      m.openTd();
      m.addStyleName(S_ICON_CELL);
      m.addStyleName("LeftMostCell");
      m.nbsp();
      m.closeTd();

      m.openTd();
      m.setStyleName(S_DATA_CELL);
      m.setAttribute("align", "right");
      if (k != null) {
        final PatchSet.Id psId = k.getKey().getParentKey();
        m.append(Util.M.patchSetHeader(psId.get()));
      } else {
        m.append("Base");
      }
      m.closeTd();

      for (int file = 0; file < sbsTable.getFileCount(); file++) {
        m.openTd();
        m.setStyleName(S_DATA_CELL);
        m.nbsp();
        m.closeTd();
      }

      m.openTd();
      m.setStyleName(S_DATA_CELL);
      if (k != null && k.getCommentCount() > 0) {
        m.append(Util.M.patchTableComments(k.getCommentCount()));
      } else {
        m.nbsp();
      }
      m.closeTd();

      m.closeTr();
    }

    private class HistoryRadio extends RadioButton {
      final PatchSet.Id patchSetId;
      final int file;

      HistoryRadio(final PatchSet.Id ps, final int f) {
        super(String.valueOf(f));
        sinkEvents(Event.ONCLICK);
        patchSetId = ps;
        file = f;
      }

      @Override
      public void onBrowserEvent(final Event event) {
        switch (DOM.eventGetType(event)) {
          case Event.ONCLICK:
            onClick(this);
            break;
          default:
            super.onBrowserEvent(event);
        }
      }
    }
  }
}
