// Copyright (C) 2013 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.actions;

import com.google.gerrit.client.api.ActionContext;
import com.google.gerrit.client.api.ChangeGlue;
import com.google.gerrit.client.api.ProjectGlue;
import com.google.gerrit.client.api.RevisionGlue;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

public class ActionButton extends Button implements ClickHandler {
  private final Project.NameKey project;
  private final ChangeInfo change;
  private final RevisionInfo revision;
  private final ActionInfo action;
  private ActionContext ctx;

  public ActionButton(Project.NameKey project, ActionInfo action) {
    this(project, null, null, action);
  }

  public ActionButton(ChangeInfo change, ActionInfo action) {
    this(change, null, action);
  }

  public ActionButton(ChangeInfo change, RevisionInfo revision,
      ActionInfo action) {
    this(null, change, revision, action);
  }

  private ActionButton(Project.NameKey project, ChangeInfo change,
      RevisionInfo revision, ActionInfo action) {
    super(new SafeHtmlBuilder()
      .openDiv()
      .append(action.label())
      .closeDiv());
    setStyleName("");
    setTitle(action.title());
    setEnabled(action.enabled());
    addClickHandler(this);

    this.project = project;
    this.change = change;
    this.revision = revision;
    this.action = action;
  }

  @Override
  public void onClick(ClickEvent event) {
    if (ctx != null && ctx.has_popup()) {
      ctx.hide();
      ctx = null;
      return;
    }

    if (revision != null) {
      RevisionGlue.onAction(change, revision, action, this);
    } else if (change != null) {
      ChangeGlue.onAction(change, action, this);
    } else if (project != null) {
      ProjectGlue.onAction(project, action, this);
    }
  }

  @Override
  public void onUnload() {
    if (ctx != null) {
      if (ctx.has_popup()) {
        ctx.hide();
      }
      ctx = null;
    }
    super.onUnload();
  }

  public void link(ActionContext ctx) {
    this.ctx = ctx;
  }

  public void unlink() {
    ctx = null;
  }
}
