// Copyright (C) 2011 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.admin;

import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;

import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.NotFoundScreen;
import com.google.gerrit.client.VoidResult;
import com.google.gerrit.client.account.AccountCapabilities;
import com.google.gerrit.client.projects.ProjectApi;
import com.google.gerrit.client.projects.ProjectInfo;
import com.google.gerrit.client.projects.ProjectMap;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.OnEditEnabler;
import com.google.gerrit.client.ui.ProjectListPopup;
import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
import com.google.gerrit.client.ui.ProjectsTable;
import com.google.gerrit.client.ui.RemoteSuggestBox;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.ProjectUtil;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwtexpui.globalkey.client.NpTextBox;

public class CreateProjectScreen extends Screen {
  private Grid grid;
  private NpTextBox project;
  private Button create;
  private Button browse;
  private RemoteSuggestBox parent;
  private CheckBox emptyCommit;
  private CheckBox permissionsOnly;
  private ProjectsTable suggestedParentsTab;
  private ProjectListPopup projectsPopup;

  public CreateProjectScreen() {
    super();
    setRequiresSignIn(true);
  }

  @Override
  protected void onLoad() {
    super.onLoad();
    AccountCapabilities.all(
        new GerritCallback<AccountCapabilities>() {
          @Override
          public void onSuccess(AccountCapabilities ac) {
            if (ac.canPerform(CREATE_PROJECT)) {
              display();
            } else {
              Gerrit.display(PageLinks.ADMIN_CREATE_PROJECT, new NotFoundScreen());
            }
          }
        },
        CREATE_PROJECT);
  }

  @Override
  protected void onUnload() {
    super.onUnload();
    projectsPopup.closePopup();
  }

  @Override
  protected void onInitUI() {
    super.onInitUI();
    setPageTitle(AdminConstants.I.createProjectTitle());
    addCreateProjectPanel();

    /* popup */
    projectsPopup =
        new ProjectListPopup() {
          @Override
          protected void onMovePointerTo(String projectName) {
            // prevent user input from being overwritten by simply poping up
            if (!projectsPopup.isPoppingUp() || "".equals(parent.getText())) {
              parent.setText(projectName);
            }
          }
        };
    projectsPopup.initPopup(AdminConstants.I.projects(), PageLinks.ADMIN_PROJECTS);
  }

  @Override
  public void onShowView() {
    super.onShowView();
    if (project != null) {
      project.setFocus(true);
    }
  }

  private void addCreateProjectPanel() {
    final VerticalPanel fp = new VerticalPanel();
    fp.setStyleName(Gerrit.RESOURCES.css().createProjectPanel());

    initCreateButton();
    initCreateTxt();
    initParentBox();

    addGrid(fp);

    emptyCommit = new CheckBox(AdminConstants.I.checkBoxEmptyCommit());
    emptyCommit.setValue(true);
    permissionsOnly = new CheckBox(AdminConstants.I.checkBoxPermissionsOnly());
    fp.add(emptyCommit);
    fp.add(permissionsOnly);
    fp.add(create);
    VerticalPanel vp = new VerticalPanel();
    vp.add(fp);
    initSuggestedParents();
    vp.add(suggestedParentsTab);
    add(vp);
  }

  private void initCreateTxt() {
    project =
        new NpTextBox() {
          @Override
          public void onBrowserEvent(Event event) {
            super.onBrowserEvent(event);
            if (event.getTypeInt() == Event.ONPASTE) {
              Scheduler.get()
                  .scheduleDeferred(
                      new ScheduledCommand() {
                        @Override
                        public void execute() {
                          if (project.getValue().trim().length() != 0) {
                            create.setEnabled(true);
                          }
                        }
                      });
            }
          }
        };
    project.sinkEvents(Event.ONPASTE);
    project.setVisibleLength(50);
    project.addKeyPressHandler(
        new KeyPressHandler() {
          @Override
          public void onKeyPress(KeyPressEvent event) {
            if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
              doCreateProject();
            }
          }
        });
    new OnEditEnabler(create, project);
  }

  private void initCreateButton() {
    create = new Button(AdminConstants.I.buttonCreateProject());
    create.setEnabled(false);
    create.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            doCreateProject();
          }
        });

    browse = new Button(AdminConstants.I.buttonBrowseProjects());
    browse.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            int top = grid.getAbsoluteTop() - 50; // under page header
            // Try to place it to the right of everything else, but not
            // right justified
            int left =
                5
                    + Math.max(
                        grid.getAbsoluteLeft() + grid.getOffsetWidth(),
                        suggestedParentsTab.getAbsoluteLeft()
                            + suggestedParentsTab.getOffsetWidth());
            projectsPopup.setPreferredCoordinates(top, left);
            projectsPopup.displayPopup();
          }
        });
  }

  private void initParentBox() {
    parent = new RemoteSuggestBox(new ProjectNameSuggestOracle());
    parent.setVisibleLength(50);
  }

  private void initSuggestedParents() {
    suggestedParentsTab =
        new ProjectsTable() {
          {
            table.setText(0, 1, AdminConstants.I.parentSuggestions());
          }

          @Override
          protected void populate(int row, ProjectInfo k) {
            populateState(row, k);
            final Anchor projectLink = new Anchor(k.name());
            projectLink.addClickHandler(
                new ClickHandler() {

                  @Override
                  public void onClick(ClickEvent event) {
                    parent.setText(getRowItem(row).name());
                  }
                });

            table.setWidget(row, ProjectsTable.C_NAME, projectLink);
            table.setText(row, ProjectsTable.C_DESCRIPTION, k.description());

            setRowItem(row, k);
          }
        };
    suggestedParentsTab.setVisible(false);

    ProjectMap.parentCandidates(
        new GerritCallback<ProjectMap>() {
          @Override
          public void onSuccess(ProjectMap list) {
            if (!list.isEmpty()) {
              suggestedParentsTab.setVisible(true);
              suggestedParentsTab.display(list);
              suggestedParentsTab.finishDisplay();
            }
          }
        });
  }

  private void addGrid(VerticalPanel fp) {
    grid = new Grid(2, 3);
    grid.setStyleName(Gerrit.RESOURCES.css().infoBlock());
    grid.setText(0, 0, AdminConstants.I.columnProjectName() + ":");
    grid.setWidget(0, 1, project);
    grid.setText(1, 0, AdminConstants.I.headingParentProjectName() + ":");
    grid.setWidget(1, 1, parent);
    grid.setWidget(1, 2, browse);
    fp.add(grid);
  }

  private void doCreateProject() {
    final String projectName = project.getText().trim();
    final String parentName = parent.getText().trim();

    if ("".equals(projectName)) {
      project.setFocus(true);
      return;
    }

    enableForm(false);
    ProjectApi.createProject(
        projectName,
        parentName,
        emptyCommit.getValue(),
        permissionsOnly.getValue(),
        new AsyncCallback<VoidResult>() {
          @Override
          public void onSuccess(VoidResult result) {
            String nameWithoutSuffix = ProjectUtil.stripGitSuffix(projectName);
            History.newItem(
                Dispatcher.toProjectAdmin(
                    new Project.NameKey(nameWithoutSuffix), ProjectScreen.INFO));
          }

          @Override
          public void onFailure(Throwable caught) {
            new ErrorDialog(caught.getMessage()).center();
            enableForm(true);
          }
        });
  }

  private void enableForm(boolean enabled) {
    project.setEnabled(enabled);
    create.setEnabled(enabled);
    parent.setEnabled(enabled);
    emptyCommit.setEnabled(enabled);
    permissionsOnly.setEnabled(enabled);
  }
}
