/*
 * Copyright 2008 Google Inc.
 * 
 * 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.gwt.user.client.impl;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Window.Location;

/**
 * History implementation for IE6 and IE7, which do not support the onhashchange
 * event, and for which {@link HistoryImplTimer} will not work either.
 */
class HistoryImplIE6 extends HistoryImpl {

  /**
   * Sanitizes an untrusted string to be used in an HTML context. NOTE: This
   * method of escaping strings should only be used on Internet Explorer.
   * 
   * @param maybeHtml untrusted string that may contain html
   * @return sanitized string
   */
  private static String escapeHtml(String maybeHtml) {
    final Element div = Document.get().createDivElement();
    div.setInnerText(maybeHtml);
    return div.getInnerHTML();
  }

  private static native Element findHistoryFrame() /*-{
    return $doc.getElementById('__gwt_historyFrame');
  }-*/;

  /**
   * For IE6, reading from $wnd.location.hash drops part of the fragment if the
   * fragment contains a '?'. To avoid this bug, we use location.href instead.
   */
  private static native String getLocationHash() /*-{
    var href = $wnd.location.href;
    var hashLoc = href.lastIndexOf("#");
    return (hashLoc > 0) ? href.substring(hashLoc) : "";
  }-*/;

  private static native Element getTokenElement(Element historyFrame) /*-{
    // Initialize the history iframe.  If '__gwt_historyToken' already exists, then
    // we're probably backing into the app, so _don't_ set the iframe's location.
    if (historyFrame.contentWindow) {
      var doc = historyFrame.contentWindow.document;
      return doc.getElementById('__gwt_historyToken');
    }
  }-*/;

  protected Element historyFrame;
  private boolean reloadedWindow;

  @Override
  public boolean init() {
    historyFrame = findHistoryFrame();
    if (historyFrame == null) {
      return false;
    }

    initHistoryToken();

    // Initialize the history iframe. If a token element already exists, then
    // we're probably backing into the app, so _don't_ create a new item.
    Element tokenElement = getTokenElement(historyFrame);
    if (tokenElement != null) {
      setToken(getTokenElementContent(tokenElement));
    } else {
      navigateFrame(getToken());
    }

    injectGlobalHandler();
    initUrlCheckTimer();
    return true;
  }

  @Override
  protected final void nativeUpdate(String historyToken) {
    /*
     * Must update the location hash since it isn't already correct.
     */
    updateHash(historyToken);
    navigateFrame(historyToken);
  }

  @Override
  protected final void nativeUpdateOnEvent(String historyToken) {
    updateHash(historyToken);
  }

  private native String getTokenElementContent(Element tokenElement) /*-{
    return tokenElement.innerText;
  }-*/;

  /**
   * The URL check timer sometimes reloads the window to work around an IE bug.
   * However, the user might cancel the page navigation, resulting in a mismatch
   * between the current history token and the URL hash value.
   * 
   * @return true if a canceled window reload was handled
   */
  private boolean handleWindowReloadCanceled() {
    if (reloadedWindow) {
      reloadedWindow = false;
      updateHash(getToken());
      return true;
    }
    return false;
  }

  private native void initHistoryToken() /*-{
    // Assume an empty token.
    var token = '';
    // Get the initial token from the url's hash component.
    var hash = @com.google.gwt.user.client.impl.HistoryImplIE6::getLocationHash()();
    if (hash.length > 0) {
      try {
        token = this.@com.google.gwt.user.client.impl.HistoryImpl::decodeFragment(Ljava/lang/String;)(hash.substring(1));
      } catch (e) {
        // Clear the bad hash (this can't have been a valid token).
        $wnd.location.hash = '';
      }
    }
    @com.google.gwt.user.client.impl.HistoryImpl::setToken(Ljava/lang/String;)(token);
  }-*/;

  private native void initUrlCheckTimer() /*-{
    // This is the URL check timer.  It detects when an unexpected change
    // occurs in the document's URL (e.g. when the user enters one manually
    // or selects a 'favorite', but only the #hash part changes).  When this
    // occurs, we _must_ reload the page.  This is because IE has a really
    // nasty bug that totally mangles its history stack and causes the location
    // bar in the UI to stop working under these circumstances.
    var historyImplRef = this;
    var urlChecker = $entry(function() {
      $wnd.setTimeout(urlChecker, 250);

      // Reset the hash if the user cancels a window reload triggered by the 
      // urlChecker.
      if (historyImplRef.@com.google.gwt.user.client.impl.HistoryImplIE6::handleWindowReloadCanceled()()) {
        return;
      }

      var hash = @com.google.gwt.user.client.impl.HistoryImplIE6::getLocationHash()();
      if (hash.length > 0) {
        var token = '';
        try {
          token = historyImplRef.@com.google.gwt.user.client.impl.HistoryImpl::decodeFragment(Ljava/lang/String;)(hash.substring(1));
        } catch (e) {
          // If there's a bad hash, always reload. This could only happen if
          // if someone entered or linked to a bad url.
          historyImplRef.@com.google.gwt.user.client.impl.HistoryImplIE6::reloadWindow()();
        }

        var historyToken = @com.google.gwt.user.client.impl.HistoryImpl::getToken()();
        if (historyToken && (token != historyToken)) {
          historyImplRef.@com.google.gwt.user.client.impl.HistoryImplIE6::reloadWindow()();
        }
      }
    });
    urlChecker();
  }-*/;

  private native void injectGlobalHandler() /*-{
    var historyImplRef = this;
    var oldOnLoad = $wnd.__gwt_onHistoryLoad;

    $wnd.__gwt_onHistoryLoad = $entry(function(token) {
      historyImplRef.@com.google.gwt.user.client.impl.HistoryImpl::newItemOnEvent(Ljava/lang/String;)(token);

      if (oldOnLoad) {
        oldOnLoad(token);
      }
    });
  }-*/;

  private native void navigateFrame(String token) /*-{
    var escaped = @com.google.gwt.user.client.impl.HistoryImplIE6::escapeHtml(Ljava/lang/String;)(token);
    var doc = this.@com.google.gwt.user.client.impl.HistoryImplIE6::historyFrame.contentWindow.document;
    doc.open();
    doc.write('<html><body onload="if(parent.__gwt_onHistoryLoad)parent.__gwt_onHistoryLoad(__gwt_historyToken.innerText)"><div id="__gwt_historyToken">' + escaped + '</div></body></html>');
    doc.close();
  }-*/;

  private void reloadWindow() {
    reloadedWindow = true;
    Location.reload();
  }

  private native void updateHash(String token) /*-{
    $wnd.location.hash = this.@com.google.gwt.user.client.impl.HistoryImpl::encodeFragment(Ljava/lang/String;)(token);
  }-*/;
}
