// Copyright (C) 2009 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.openid;

import com.google.gerrit.client.SignInDialog;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.FormElement;
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.Cookies;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwtexpui.globalkey.client.NpTextBox;

import java.util.Map;

public class OpenIdLoginPanel extends Composite implements
    FormPanel.SubmitHandler {
  private final SignInDialog.Mode mode;
  private final LoginIcons icons;
  private final FlowPanel panelWidget;
  private final FormPanel form;
  private final FlowPanel formBody;
  private final FormPanel redirectForm;
  private final FlowPanel redirectBody;

  private FlowPanel errorLine;
  private InlineLabel errorMsg;

  private Button login;
  private NpTextBox providerId;
  private CheckBox rememberId;
  private boolean discovering;

  public OpenIdLoginPanel(final SignInDialog.Mode requestedMode,
      final String initialErrorMsg) {
    mode = requestedMode;

    icons = GWT.create(LoginIcons.class);

    formBody = new FlowPanel();
    formBody.setStyleName("gerrit-OpenID-loginform");

    form = new FormPanel();
    form.setMethod(FormPanel.METHOD_GET);
    form.addSubmitHandler(this);
    form.add(formBody);

    redirectBody = new FlowPanel();
    redirectBody.setVisible(false);
    redirectForm = new FormPanel();
    redirectForm.add(redirectBody);

    panelWidget = new FlowPanel();
    panelWidget.add(form);
    panelWidget.add(redirectForm);
    initWidget(panelWidget);

    createHeaderLogo();
    createHeaderText();
    createErrorBox();
    createIdentBox();

    link(OpenIdUtil.URL_GOOGLE, OpenIdUtil.C.nameGoogle(), icons.iconGoogle());
    link(OpenIdUtil.URL_YAHOO, OpenIdUtil.C.nameYahoo(), icons.iconYahoo());

    if (initialErrorMsg != null) {
      showError(initialErrorMsg);
    }
    formBody.add(new HTML(OpenIdUtil.C.whatIsOpenIDHtml()));
  }

  public void setFocus(final boolean take) {
    if (take) {
      providerId.selectAll();
    }
    providerId.setFocus(take);
  }

  private void createHeaderLogo() {
    final FlowPanel headerLogo = new FlowPanel();
    headerLogo.setStyleName("gerrit-OpenID-logobox");
    headerLogo.add(icons.openidLogo().createImage());
    formBody.add(headerLogo);
  }

  private void createHeaderText() {
    final FlowPanel headerText = new FlowPanel();
    final String me = Window.Location.getHostName();
    final SmallHeading headerLabel = new SmallHeading();
    switch (mode) {
      case LINK_IDENTIY:
        headerLabel.setText(OpenIdUtil.M.linkAt(me));
        break;
      case REGISTER:
        headerLabel.setText(OpenIdUtil.M.registerAt(me));
        break;
      case SIGN_IN:
      default:
        headerLabel.setText(OpenIdUtil.M.signInAt(me));
        break;
    }
    headerText.add(headerLabel);
    formBody.add(headerText);
  }

  private void createErrorBox() {
    errorLine = new FlowPanel();
    errorLine.setVisible(false);

    errorMsg = new InlineLabel();
    errorLine.setStyleName("gerrit-OpenID-errorline");
    errorLine.add(errorMsg);
    formBody.add(errorLine);
  }

  private void showError(final String msgText) {
    errorMsg.setText(msgText);
    errorLine.setVisible(true);
  }

  private void hideError() {
    errorLine.setVisible(false);
  }

  private void createIdentBox() {
    final FlowPanel group = new FlowPanel();
    group.setStyleName("gerrit-OpenID-loginline");

    final FlowPanel line1 = new FlowPanel();
    group.add(line1);

    providerId = new NpTextBox();
    providerId.setVisibleLength(60);
    providerId.setStyleName("gerrit-OpenID-openid_identifier");
    providerId.setTabIndex(0);
    providerId.addKeyPressHandler(new KeyPressHandler() {
      @Override
      public void onKeyPress(final KeyPressEvent event) {
        if (event.getCharCode() == KeyCodes.KEY_ENTER) {
          event.preventDefault();
          form.submit();
        }
      }
    });
    line1.add(providerId);

    login = new Button();
    switch (mode) {
      case LINK_IDENTIY:
        login.setText(OpenIdUtil.C.buttonLinkId());
        break;
      case REGISTER:
        login.setText(OpenIdUtil.C.buttonRegister());
        break;
      case SIGN_IN:
      default:
        login.setText(OpenIdUtil.C.buttonSignIn());
        break;
    }
    login.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        form.submit();
      }
    });
    login.setTabIndex(2);
    line1.add(login);

    if (mode == SignInDialog.Mode.SIGN_IN) {
      rememberId = new CheckBox(OpenIdUtil.C.rememberMe());
      rememberId.setTabIndex(1);
      group.add(rememberId);

      final String last = Cookies.getCookie(OpenIdUtil.LASTID_COOKIE);
      if (last != null && !"".equals(last)) {
        providerId.setText(last);
        rememberId.setValue(true);
      }
    }

    formBody.add(group);
  }

  private void link(final String identUrl, final String who,
      final AbstractImagePrototype icon) {
    final ClickHandler i = new ClickHandler() {
      @Override
      public void onClick(final ClickEvent event) {
        if (!discovering) {
          providerId.setText(identUrl);
          form.submit();
        }
      }
    };

    final FlowPanel line = new FlowPanel();
    line.addStyleName("gerrit-OpenID-directlink");

    final Image img = icon.createImage();
    img.addClickHandler(i);
    line.add(img);

    final InlineLabel lbl = new InlineLabel();
    switch (mode) {
      case LINK_IDENTIY:
        lbl.setText(OpenIdUtil.M.linkWith(who));
        break;
      case REGISTER:
        lbl.setText(OpenIdUtil.M.registerWith(who));
        break;
      case SIGN_IN:
      default:
        lbl.setText(OpenIdUtil.M.signInWith(who));
        break;
    }
    lbl.addClickHandler(i);
    line.add(lbl);

    formBody.add(line);
  }

  private void enable(final boolean on) {
    providerId.setEnabled(on);
    login.setEnabled(on);
  }

  private void onDiscovery(final DiscoveryResult result) {
    discovering = false;

    if (result.validProvider) {
      redirectForm.setMethod(FormPanel.METHOD_POST);
      redirectForm.setAction(result.providerUrl);
      redirectBody.clear();
      for (final Map.Entry<String, String> e : result.providerArgs.entrySet()) {
        redirectBody.add(new Hidden(e.getKey(), e.getValue()));
      }

      // The provider won't support operation inside an IFRAME, so we
      // replace our entire application. No fancy waits are needed,
      // the browser won't update anything until its started to load
      // the provider's page.
      //
      FormElement.as(redirectForm.getElement()).setTarget("_top");
      redirectForm.submit();

    } else {
      // We failed discovery. We have to use a deferred command here
      // as we are being called from within an invisible IFRAME. Jump
      // back to the main event loop in the parent window.
      //
      onDiscoveryFailure();
    }
  }

  private void onDiscoveryFailure() {
    showError(OpenIdUtil.C.notSupported());
    enable(true);
    providerId.selectAll();
    providerId.setFocus(true);
  }

  @Override
  public void onSubmit(final SubmitEvent event) {
    event.cancel();

    final String openidIdentifier = providerId.getText();
    if (openidIdentifier == null || openidIdentifier.equals("")) {
      enable(true);
      return;
    }

    discovering = true;
    enable(false);
    hideError();

    final boolean remember = rememberId != null && rememberId.getValue();
    final String token = History.getToken();
    OpenIdUtil.SVC.discover(openidIdentifier, mode, remember, token,
        new GerritCallback<DiscoveryResult>() {
          public void onSuccess(final DiscoveryResult result) {
            onDiscovery(result);
          }

          @Override
          public void onFailure(final Throwable caught) {
            super.onFailure(caught);
            onDiscoveryFailure();
          }
        });
  }

  public void onSubmitComplete(final FormSubmitCompleteEvent event) {
  }
}
