﻿// Register the namespace for the control.
Type.registerNamespace('Polyton.Web.UI');

Polyton.Web.UI.HistoryEventArgs = function(entry) {
  Polyton.Web.UI.HistoryEventArgs.initializeBase(this);

  var _entry = entry;
}

Polyton.Web.UI.HistoryEventArgs.prototype = {
  get_entry: function() {
    return this._entry;
  }
}

Polyton.Web.UI.HistoryEventArgs.registerClass('Polyton.Web.UI.HistoryEventArgs', Sys.EventArgs);


Polyton.Web.UI.HistoryControl = function(element) {
  Polyton.Web.UI.HistoryControl.initializeBase(this, [element]);
  // Sys.Runtime.registerDisposableObject(this);

  var _historyIFrame;
  var _ignoreIFrame = true;
  var _ignoreTimer = false;
  var _currentEntry = '';

  var _appLoadHandler = null;
  var _iframeLoadHandler;

  var _idleTimerCookie = 0;

  this._timer = null;
  this._interval = 100;
  this._enabled = false;

  this._uniqueID = null;
  this._callbackTarget = null;

  this._endRequestHandlerDelegate = null;
  this._endTestNavigateHandlerDelegate = null;
  this._pageRequestManager = null;
}

Polyton.Web.UI.HistoryControl.prototype = {

  _frameLiteral: "__historyFrame",
  _emptyUrl: "empty.html",

  _testIE: function() {
    var userAgent = navigator.userAgent.toLowerCase();
    if (document.all && userAgent.indexOf('msie') != -1) {
      return true;
    }
    else {
      return false;
    }
  },

  get_interval: function() {
    /// <value type="Number">Interval in milliseconds</value>
    return this._interval;
  },
  set_interval: function(value) {
    if (this._interval != value) {
      this._interval = value;
      this.raisePropertyChanged('interval');

      if (!this.get_isUpdating() && (this._timer != null)) {
        this._restartTimer();
      }
    }
  },

  get_enabled: function() {
    /// <value type="Boolean">True if timer is enabled, false if disabled.</value>
    return this._enabled;
  },
  set_enabled: function(value) {
    if (value != this.get_enabled()) {
      this._enabled = value;
      this.raisePropertyChanged('enabled');
      if (!this.get_isUpdating()) {
        if (value) {
          this._startTimer();
        }
        else {
          this._stopTimer();
        }
      }
    }
  },

  _handleEndNavigate: function(result) {
    if (result) {
      this.add_Entry(result);
    }
  },


  _handleEndRequest: function(sender, arg) {
    var dataItem = arg.get_dataItems()[this.get_uniqueID().replace(/\$/g, '_')];
    if (dataItem) {
      this.add_Entry(dataItem[2]);
      //this._update(dataItem[0],dataItem[1]);
    }
  },


  get_CurrentEntry: function() {
    var entry = window.location.hash;
    if ((entry.length >= 1) && (entry.charAt(0) == '#')) {
      entry = entry.substring(1);
    }
    return entry;
  },

  set_CurrentEntry: function(value) {
    this._currentEntry = value;
    //    debugger;
    window.location.hash = value;
  },


  back: function() {
    window.history.back();
  },

  forward: function() {
    window.history.forward();
  },

  add_Entry: function(entry) {
    this._ignoreTimer = true;
    if (this._historyIFrame) {
      this._ignoreIFrame = true;
      this._historyIFrame.src = this._emptyUrl + "?" + entry;
    }
    else {
      this.set_CurrentEntry(entry);
    }
  },

  updated: function() {
    Polyton.Web.UI.HistoryControl.callBaseMethod(this, 'updated');
    // called after batch updates, this.beginUpdate(), this.endUpdate().
    if (this._enabled) {
      this._restartTimer();
    }
  },

  dispose: function() {
    // Sys.Runtime.unregisterDisposableObject(this)

    if (this._historyIFrame) {
      this._historyIFrame.detachEvent('onload', this._iframeLoadHandler);
    }
    this._iframeLoadHandler = null;

    if (this._pageRequestManager != null) {
      this._pageRequestManager.remove_endRequest(this._endRequestHandlerDelegate);
    }

    // call set_enabled so the property changed event fires, for potentially attached listeners.
    this.set_enabled(false);
    // make sure it stopped so we aren't called after disposal
    this._stopTimer();
    // be sure to call base.dispose()
    Polyton.Web.UI.HistoryControl.callBaseMethod(this, 'dispose');
  },

  initialize: function() {
    Polyton.Web.UI.HistoryControl.callBaseMethod(this, 'initialize');

    this._historyIFrame = $get(this._frameLiteral);
    if (this._historyIFrame == null && this._testIE()) {
      this._historyIFrame = document.createElement("iframe");
      this._historyIFrame.id = this._frameLiteral;
      this._historyIFrame.style.display = "none";
      this._historyIFrame.src = this._emptyUrl + "?" + this.get_CurrentEntry();

      if (document.body.firstChild)
        document.body.insertBefore(this._historyIFrame, document.body.firstChild);
      else
        document.body.appendChild(this._historyIFrame);
    }

    if (this._historyIFrame) {
      this._ignoreIFrame = false;

      this._iframeLoadHandler = Function.createDelegate(this, this._onIFrameLoad);
      this._historyIFrame.attachEvent('onload', this._iframeLoadHandler);
    }

    this._endRequestHandlerDelegate = Function.createDelegate(this, this._handleEndRequest);
    this._endTestNavigateHandlerDelegate = Function.createDelegate(this, this._handleEndNavigate);
    if (Sys.WebForms && Sys.WebForms.PageRequestManager) {
      this._pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
    }
    if (this._pageRequestManager != null) {
      this._pageRequestManager.add_endRequest(this._endRequestHandlerDelegate);
    }

    this._currentEntry = this.get_CurrentEntry();
    if (this._currentEntry != "") {
      this._onNavigate(this._currentEntry);
    }

    if (this.get_enabled()) {
      this._startTimer();
    }
  },

  _onIFrameLoad: function() {
    var entry = this._historyIFrame.contentWindow.location.search;
    if ((entry.length >= 1) && (entry.charAt(0) == '?')) {
      entry = entry.substring(1);
    }

    if (this._currentEntry != entry) {
      this.set_CurrentEntry(entry);
      if (this._ignoreIFrame) {
        this._ignoreIFrame = false;
        return;
      }
      this._onNavigate(entry);
    }
    else if (this._ignoreIFrame) {
      this._ignoreIFrame = false;
      return;
    }
  },

  get_uniqueID: function() {
    /// <value type="String"></value>
    if (arguments.length != 0) throw Error.parameterCount();
    return this._uniqueID;
  },

  set_uniqueID: function(value) {
    this._uniqueID = value;
  },

  _doPostback: function(eventArgs) {
    __doPostBack(this.get_uniqueID(), eventArgs);

    //this._invoke('TestNavigate', [eventArgs], this._endTestNavigateHandlerDelegate);

  },

  // events    
  add_Navigate: function(handler) {
    /// <summary>Adds a event handler for the tick event.</summary>
    /// <param name="handler" type="Function">The handler to add to the event.</param>
    this.get_events().addHandler("Navigate", handler);
  },

  remove_Navigate: function(handler) {
    /// <summary>Removes a event handler for the tick event.</summary>
    /// <param name="handler" type="Function">The handler to remove from the event.</param>
    this.get_events().removeHandler("Navigate", handler);
  },

  _onNavigate: function(eventArgs) {
    var handler = this.get_events().getHandler("Navigate");
    if (handler) {
      handler(this, eventArgs);
    }
    // debugger;
    this._doPostback(eventArgs);

  },

  _restartTimer: function() {
    this._stopTimer();
    this._startTimer();
  },

  _startTimer: function() {
    // save timer cookie for removal later
    this._timer = window.setTimeout(Function.createDelegate(this, this._timerCallback), this._interval);
  },

  _stopTimer: function() {
    if (this._timer) {
      window.clearTimeout(this._timer);
      this._timer = null;
    }
  },

  _timerCallback: function() {
    this._timer = 0;

    var entry = this.get_CurrentEntry();
    if (entry != this._currentEntry) {
      this._currentEntry = entry;
      if (!this._ignoreTimer) {
        this._onNavigate(entry);
      }
    }
    this._ignoreTimer = false;
    this._startTimer();
  }
}

// JSON object that describes all properties, events, and methods of this component that should
// be addressable through the Sys.TypeDescriptor methods, and addressable via xml-script.
Polyton.Web.UI.HistoryControl.descriptor = {
  properties: [{ name: 'interval', type: Number },
                    { name: 'enabled', type: Boolean },
                    { name: 'uniqueID', type: String}],
  events: [{ name: 'Navigate'}]
}


Polyton.Web.UI.HistoryControl.registerClass('Polyton.Web.UI.HistoryControl', AjaxControlToolkit.ControlBase);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();