
Components.utils.import("resource://yoono/yoonoYEXTIF.js");
Components.utils.import("resource://yoono/yoonoPrefs.js");
Components.utils.import("resource://yoono/yoonoCookies.js");

var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;

var screenManager = Components.classes["@mozilla.org/gfx/screenmanager;1"].getService(Components.interfaces.nsIScreenManager);



var ynWebPanel = {};

ynWebPanel._iframe = null;
ynWebPanel._progress = null;
ynWebPanel._status = null;
ynWebPanel._title = null;

ynWebPanel.init = function (onReadyCallback) {
  ynWebPanel._domWin = window;
  ynWebPanel._onMainDOMLoaded();
  if (typeof onReadyCallback=="function")
    onReadyCallback();
}

ynWebPanel._onMainDOMLoaded = function () {
  this._panel = document.getElementById("browser-panel");
  this._iframe = document.getElementById("website-iframe");
  this._progress = document.getElementById("website-progress");
  this._status = document.getElementById("website-status");
  this._title = document.getElementById("urlbar");
  this._openInBrowserButton = document.getElementById("website-open-in-browser");
  
  if (navigator.platform.indexOf("Mac")!=-1)
    document.documentElement.className+=" desktop-mac";
  else if (navigator.platform.indexOf("Linux")!=-1)
    document.documentElement.className+=" linux";
  
  //
  // Register all DOM listeners

  this._previousBtn = document.getElementById("website-go-previous");
  this._previousBtn.addEventListener("click", function () {
    ynWebPanel.goBack();
  },true);
  
  this._nextBtn = document.getElementById("website-go-next");
  this._nextBtn.addEventListener("click", function () {
    ynWebPanel.goNext();
  },true);
  
  var shareBtn = document.getElementById("website-share-button");
  shareBtn.addEventListener("click", function () {
    var iframe = document.getElementById("main-iframe");
    var iframeWin = iframe.contentWindow;
    if (iframeWin.wrappedJSObject)
      iframeWin = iframeWin.wrappedJSObject;
    var sidebar = iframeWin.ynSidebar;
    sidebar.shortcutClick();
  },true);
  
//  var header = document.getElementById("website-header");
//  header.addEventListener("dblclick", function () {
//    ynWebPanel.maximize();
//  },false);
  
  var openInBrowserBtn = document.getElementById("website-open-in-browser");
  openInBrowserBtn.addEventListener("click", function () {
//    ynWebPanel.close();
    ynWebPanel.openCurrentInSystemBrowser();
  },false);
  
  function updatePref(newValue) {
    YOONO_PREFS.set("open-in-system-browser",newValue);
    prefCheckbox.checked = newValue;
    prefRadioYoono.setAttribute("selected",!newValue?"true":"false");
    prefRadioSystem.setAttribute("selected",newValue?"true":"false");
  }
  var prefRadioYoono = document.getElementById("website-open-in-browser-pref-yoono");
  var prefRadioSystem = document.getElementById("website-open-in-browser-pref-system");
  var prefCheckbox = document.getElementById("open-in-browser-pref");
  prefRadioYoono.addEventListener("command", function () {
    updatePref(false);
  },true);
  prefRadioSystem.addEventListener("command", function () {
    updatePref(true);
  },true);
  prefCheckbox.addEventListener("command", function () {
    updatePref(prefCheckbox.checked);
  },true);

  
  updatePref(YOONO_PREFS.get("open-in-system-browser"));
  
  //
  // Setup all listener needed to watch website events
  this._iframe.addEventListener("load",function (event) {
    if (event.originalTarget!=ynWebPanel._iframe.contentDocument) return;
    YOONO_YEXTIF.notifyTabActivity(windowId, event.originalTarget, ynWebPanel._iframe.contentDocument.location.href, 'loaded');
    ynWebPanel._progress.hidden = true;
    ynWebPanel._status.hidden = true;
    ynWebPanel._status.value = "";
  },true);
  
  this._iframe.addEventListener("DOMContentLoaded",function (event) {
    if (event.originalTarget!=ynWebPanel._iframe.contentDocument) return;
    YOONO_YEXTIF.notifyTabActivity(windowId, ynWebPanel._iframe.contentDocument, ynWebPanel._iframe.contentDocument.location.href, 'domcontentloaded');
  },true);
  
//  this._iframe.addEventListener("DOMTitleChanged",function (event) {
//      if (event.originalTarget!=ynWebPanel._iframe.contentDocument) return;
//      ynWebPanel._title.value = ynWebPanel._iframe.contentDocument.title;
//  },false);
  
  this._iframe.addEventListener("keypress",function (e) {
    if (e.target.tagName=="INPUT" || e.target.tagName=="TEXTAREA" || e.target.contentEditable=="true" || e.target.ownerDocument.designMode=="on") return;
    if (e.keyCode == 8) {
      return ynWebPanel.goBack();
    }
    
  },false);

  
  var req = this._iframe.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  var prog = req.getInterface(Components.interfaces.nsIWebProgress);
  
  prog.addProgressListener(this._browserProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  
  this._domWin.QueryInterface(Components.interfaces.nsIDOMChromeWindow).browserDOMWindow = {
    QueryInterface : function(aIID)
    {
      if (aIID.equals(Components.interfaces.nsIBrowserDOMWindow) ||
          aIID.equals(Components.interfaces.nsISupports))
        return this;
      throw Components.results.NS_NOINTERFACE;
    },
    openURI : function(aURI, aOpener, aWhere, aContext)
    {
      return ynWebPanel._iframe.contentWindow;
    },

    isTabContentWindow : function(aWindow)
    {
      // Shouldn't ever get called
      throw Components.results.NS_ERROR_UNEXPECTED;
    }

  };
  
  CookiesService.registerBrowser(this._iframe);
  
}

/* /!\ Take care : this!=ynWebPanel /!\ */
ynWebPanel._domClick = function(aEvent) {
  var link = aEvent.target;

  if (link instanceof HTMLAnchorElement /*&& 
      link.target != "" &&
      link.target != "_self" &&
      link.target != "_top"*/) {
    //aEvent.stopPropagation();
  }
}

/* /!\ Take care : this!=ynWebPanel /!\ */
ynWebPanel._domActivate = function(aEvent) {
  var link = aEvent.target;
  
  if (link instanceof HTMLAnchorElement /*&& 
      link.target != "" &&
      link.target != "_self" &&
      link.target != "_top"*/) {
    
    //aEvent.preventDefault();
    //aEvent.stopPropagation();
    
    //ynWebPanel.openUrl(link.href);
    //ynWebPanel.openUrlInSystemBrowser(link.href);
  }
}

/* /!\ Take care : this!=ynWebPanel /!\ */
ynWebPanel._domUnload = function(aEvent) {
  aEvent.target.ownerDocument.removeEventListener("click", this._domClick, true);
  aEvent.target.ownerDocument.removeEventListener("DOMActivate", this._domActivate, true);
  aEvent.target.ownerDocument.removeEventListener("unload", this._domUnload, false);
}

ynWebPanel._browserProgressListener = {
  QueryInterface: function(iid) {
    if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
        iid.equals(Components.interfaces.nsISupportsWeakReference) ||
        iid.equals(Components.interfaces.nsISupports))
      return this;
    
    throw Components.results.NS_ERROR_NO_INTERFACE;
  },
  _requestsStarted : 0,
  _requestsFinished : 0,
  onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
    if (aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
      if (aStateFlags & nsIWebProgressListener.STATE_START) {
        this._requestsStarted++;
      }
      else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
        this._requestsFinished++;
      }
      
      if (this._requestsStarted > 1) {
        var value = (100 * this._requestsFinished) / this._requestsStarted;
        ynWebPanel._progress.setAttribute("mode", "determined");
        ynWebPanel._progress.setAttribute("value", value + "%");
      }
    }

    if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
      if (aStateFlags & nsIWebProgressListener.STATE_START) {
        ynWebPanel._progress.hidden = false;
        ynWebPanel._status.hidden = false;
        ynWebPanel._status.value = "";
      }
      else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
        ynWebPanel._progress.hidden = true;
        ynWebPanel._status.hidden = true;
        ynWebPanel._status.value = "";
        this.onStatusChange(aWebProgress, aRequest, 0, "Done");
        this._requestsStarted = this._requestsFinished = 0;
      }      
    }
    
    if (aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) {
      if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
        var domDocument = aWebProgress.DOMWindow.document;
        domDocument.addEventListener("click", ynWebPanel._domClick, true);
        domDocument.addEventListener("DOMActivate", ynWebPanel._domActivate, true);
        domDocument.addEventListener("unload", ynWebPanel._domUnload, false);
        
      }
    }
  },

  // This method is called to indicate progress changes for the currently
  // loading page.
  onProgressChange: function(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
    if (this._requestsStarted == 1) {
      if (aMaxSelf == -1) {
        ynWebPanel._progress.setAttribute("mode", "undetermined");
      }
      else {
        ynWebPanel._progress.setAttribute("mode", "determined");
        ynWebPanel._progress.setAttribute("value", ((100 * aCurSelf) / aMaxSelf) + "%");
      }
    }
  },

  // This method is called to indicate a change to the current location.
  onLocationChange: function(aWebProgress, aRequest, aLocation) {
    ynWebPanel._previousBtn.className=ynWebPanel._iframe.canGoBack?"active":"";
    ynWebPanel._nextBtn.className=ynWebPanel._iframe.canGoForward?"active":"";
//    ynWebPanel._url.value = aLocation.spec;
//    ynWebPanel._url.className = aLocation.scheme=="https"?"secure":"";
    ynWebPanel._title.value = aLocation.spec;
    YOONO_YEXTIF.notifyTabActivity(windowId, aWebProgress.DOMWindow.document, aLocation.spec, 'loadstart');
  },

  // This method is called to indicate a status changes for the currently
  // loading page.  The message is already formatted for display.
  onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
    ynWebPanel._status.setAttribute("value", aMessage);
  },

  // This method is called when the security state of the browser changes.
  onSecurityChange: function(aWebProgress, aRequest, aState) {
//    var security = document.getElementById("security");
//
//    var level = "unknown";
//    switch (aState) {
//      case nsIWebProgressListener.STATE_IS_SECURE | nsIWebProgressListener.STATE_SECURE_HIGH:
//        security.setAttribute("level", "high");
//        break;
//      case nsIWebProgressListener.STATE_IS_SECURE | nsIWebProgressListener.STATE_SECURE_MEDIUM:
//        security.setAttribute("level", "med");
//        break;
//      case nsIWebProgressListener.STATE_IS_SECURE | nsIWebProgressListener.STATE_SECURE_LOW:
//        security.setAttribute("level", "low");
//        break;
//      case nsIWebProgressListener.STATE_IS_BROKEN:
//        security.setAttribute("level", "broken");
//        break;
//      case nsIWebProgressListener.STATE_IS_INSECURE:
//      default:
//        security.removeAttribute("level");
//        break;
//    }
  }

}; // end of ynWebPanel._browserProgressListener


///////////////////////////////////////
// Public methods

ynWebPanel.openUrlInSystemBrowser = function (url) {
  // Open in system web browser
  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                            .getService(Components.interfaces.nsIIOService);
  var uri = ioService.newURI(url, null, null);
  var extProtocolSvc = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
                                 .getService(Components.interfaces.nsIExternalProtocolService);

  if(extProtocolSvc.externalProtocolHandlerExists("http")) {
    var protoInfo = extProtocolSvc.getProtocolHandlerInfo("http");
    if (protoInfo) {
      return protoInfo.launchWithURI(uri,null);
    }
  } else {
    extProtocolSvc.loadURI(uri,null);
  }
}

ynWebPanel.show = function () {
  ynWindowHandlers.expand("browser");
  this._panel.hidden=false;
}

ynWebPanel.close = function () {
  var nav = this._iframe.webNavigation;
  nav.loadURI("about:blank", 0, null, null, null);
  this._panel.hidden=true;
  YOONO_YEXTIF.notifyTabActivity(windowId, this._iframe.contentDocument, "about:blank", 'close');
  
//  document.getElementById("tab-browser").hidden=true;

  if (document.getElementById("tab-columns").hidden)
    ynWindowHandlers.collapse();
  else
    ynWindowHandlers.expand("columns");
}

ynWebPanel.getBrowser = function () {
  return this._iframe;
}

ynWebPanel.openBrowser = function (mandatoryInXulrunner) {
  ynWindowHandlers.expandBrowser();
  this._openInBrowserButton.hidden = mandatoryInXulrunner;
//  document.getElementById("tab-browser").hidden=false;
  
  trayIcon.restore(function () {
  
    ynWebPanel.refreshPopupSize(true);
    ynWebPanel.refreshPopupPosition(true);
    
    ynWebPanel.show();
    
    // /!\ moz'hack in order to see scrollbars ... 
    ynWebPanel._iframe.style.overflow="auto";
    
  });
  
  return this._iframe;
}

ynWebPanel.openCurrentInSystemBrowser = function () {
  this.openUrlInSystemBrowser(this._iframe.contentDocument.location.href);
}

ynWebPanel.goBack = function () {
  this._iframe.goBack();
  ynWebPanel.panelHiddenWorkaround();
}

ynWebPanel.goNext = function () {
  this._iframe.goForward();
  ynWebPanel.panelHiddenWorkaround();
}

ynWebPanel.goHome = function () {
  ynWindowHandlers.openPage(HOME);
}

ynWebPanel.refresh = function () {
  var iframeWin = ynWebPanel._iframe.contentWindow;
  if (iframeWin.wrappedJSObject)
    iframeWin = iframeWin.wrappedJSObject;
  var current = iframeWin.document.location.href;
  iframeWin.document.location.reload();
}

ynWebPanel.panelHiddenWorkaround = function() {
  setTimeout(function() {
    ynWebPanel._iframe.style.display="none";
    setTimeout(function() {
    ynWebPanel._iframe.style.display=null;
    }, 1);
  }, 1);
}

ynWebPanel._screenBorder = 2;
ynWebPanel.refreshPopupSize = function (forceRefresh) {
//  if (!forceRefresh && !this._baseWin.enabled) return;
//
//  var sc = screenManager.screenForRect(window.screenX, window.screenY, window.outerWidth, window.outerHeight);
//  var screenLeft = {},screenTop = {},screenWidth = {},screenHeight = {};
//  sc.GetAvailRect(screenLeft, screenTop, screenWidth, screenHeight);
//
//  var margin = ynWebPanel._screenBorder*2;
//  var maxScreenWidth = screenWidth.value;
//  if (this._mayDisplayLeft(screenLeft.value, screenWidth.value)) { // display at left
//    maxScreenWidth = window.screenX-screenLeft.value-margin;
//  } else { // display at right
//    maxScreenWidth = screenWidth.value-window.outerWidth-(window.screenX-screenLeft.value)-margin;
//  }
//  var maxScreenHeight = screenHeight.value-margin;
//
//  var w = Math.max(600,Math.min(maxScreenWidth,1024));
//  var h = Math.max(600,maxScreenHeight);
//  w = maxScreenWidth;
//  h = maxScreenHeight
//  this._domWin.resizeTo(w, h);
//
}

ynWebPanel.startMoving = function () {
  // No longer useful since window no longer transparent (perf issues otherwise)
//  this._iframe.style.visibility="hidden";
  //this._iframe.parentNode.style.background="url('chrome://yoonorunner/skin/move.png') center no-repeat";
}
ynWebPanel.endMoving = function () {
  // No longer useful since window no longer transparent (perf issues otherwise)
  //  this._iframe.style.visibility="visible";
  //this._iframe.parentNode.style.background=null;
}
ynWebPanel.refreshPopupPosition = function (forceRefresh) {
//  if (!forceRefresh && !this._baseWin.enabled) return;
//
//  var sc = screenManager.screenForRect(window.screenX, window.screenY, window.outerWidth, window.outerHeight);
//  var screenLeft = {},screenTop = {},screenWidth = {},screenHeight = {};
//  sc.GetAvailRect(screenLeft, screenTop, screenWidth, screenHeight);
//
//  var x = 0;
//  var y = screenTop.value+ynWebPanel._screenBorder;
//  if (this._mayDisplayLeft(screenLeft.value, screenWidth.value)) { // display at left
//    x = window.screenX-this._domWin.outerWidth-ynWebPanel._screenBorder;
//  } else { // display at right
//    x = window.screenX+window.outerWidth+ynWebPanel._screenBorder;
//  }
//  this._domWin.moveTo(x, y);
}

ynWebPanel.maximize = function () {
  var sc = screenManager.screenForRect(window.screenX, window.screenY, window.outerWidth, window.outerHeight);
  var screenLeft = {},screenTop = {},screenWidth = {},screenHeight = {};
  sc.GetAvailRect(screenLeft, screenTop, screenWidth, screenHeight);
  if (this._mayDisplayLeft(screenLeft.value, screenWidth.value)) {
    ynWindowHandlers.moveRight();
  } else {
    ynWindowHandlers.moveLeft();
  }
}

ynWebPanel._mayDisplayLeft = function (screenLeft, screenWidth) {
  return ((window.screenX-screenLeft)+window.outerWidth/2)>(screenWidth/2);
}

window.addEventListener("load",function () {
  
  ynWebPanel.init();
  
},false);
