// FIXME Dojo has an animation when opening / closing the dialog, but we don't want it.

// FIXME Condition for checking the resource shouldn't be here!!! It should be
// the result of Dojo builder!!!
if(!dojo._hasResource["ues.core.webui.Dialog"]){
  dojo._hasResource["ues.core.webui.Dialog"]=true;
  dojo.provide("ues.core.webui.Dialog");
  dojo.require("dijit.layout.ContentPane");
  dojo.require("dijit.Dialog");
  dojo.require("dojox.layout.ResizeHandle");
  dojo.require("dojox.image"); // for preloading capability
  dojo.require("ues.core.webui._DialogMover");
  dojo.require("ues.core.webui.form.Button"); // for MessageDialog-s
  dojo.requireLocalization("ues.core.webui", "dialog");

  // override positioning of dialog underlay on handhelds
  (function () {
    var origLayout = dijit.DialogUnderlay.prototype.layout;
    dojo.extend(dijit.DialogUnderlay, {
      layout: function () {
        if (!UES.isHandheld) return origLayout.apply(this, arguments);

        var is = this.node.style,
        os = this.domNode.style;

        // hide the background temporarily, so that the background itself isn't
        // causing scrollbars to appear (might happen when user shrinks browser
        // window and then we are called to resize)
        os.display = "none";
        os.top = "0px";
        os.left = "0px";
        is.width = document.documentElement.scrollWidht + "px";
        is.height = document.documentElement.scrollHeight + "px";
        os.display = "block";
      }
    });
  })();

  (function () {

  dojo.declare("ues.core.webui.Dialog", [dijit.Dialog], {
    autofocus: false,
    draggable: !UES.isHandheld,
    duration: 1,
    //resizeX: !UES.isHandheld, // TODO Implement if needed.
    resizeY: !UES.isHandheld,
    // FIXME Implement - "resizable" shall control, whether the dialog is resizable (i.e.
    // controls for resize are shown / hidden). "resizeX" and "resizeY" shall control
    // which direction the resize shall be possible (but they shouldn't control whether
    // the functionality is turned on/off - that's the job of "resizable" attribute).
    //resizable: !UES.isHandheld,
    shadow: true,
    minHeight: 50,
    dragHandleClass: "drag-obj",
    width: "auto", // width of the content pane
    underlay: true, // whether to display underlay layer
    autoPosition: true, // whether to position the dialog when resize / scroll events happen
    showLoading: false, // modifying this attribute switches the dialog between showing the contents and showing
    templateString: dojo.cache("ues.core.webui", "resources/templates/Dialog.html", "<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n    <span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" dojoAttachEvent=\"onclick: onCancel, onmouseenter: _onCloseEnter, onmouseleave: _onCloseLeave\" title=\"${buttonCancel}\">\n        <span dojoAttachPoint=\"closeText\" class=\"closeText\" title=\"${buttonCancel}\">x</span>\n    </span>\n    <div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n        <span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\"></span>\n    </div>\n    <div dojoAttachPoint=\"containerNode\" class=\"dijitDialogPaneContent\"></div>\n    <div class=\"ues-core-webui-dialog_loadingNode loadingProgress\">\n      <img class=\"progressIcon\" src=\"${_loadingIconSrc}\">\n      <span class=\"progressTitle\" dojoAttachPoint=\"_loadingTextNode\"></span>\n    </div>\n</div>"),
    /** The dialog icon to show in the title (only when title is specified). */
    titleIcon: null,
    _uesTitle: null,
    _prevTitle: null,
    _resizeConnects: [],
    _resizeSubscribes: [],
    _resizeLayer: null,
    _dragConnects: [],
    _dragSubscribes: [],
    _dragLayer: null,
    _active: false, // FIXME Management of this attribute should be done from this class, not from outside (VCModalWindow).
    _loadingIconSrc: UES.Util.getRealImagePath("/images/other/loading_large.gif"),
    _loadingTextNode: null, // at this point the localized string isn't on page yet => fill it in _setup()
    postMixInProperties: function () {
      this.inherited(arguments);
      this["class"] += " ues-core-webui-dialog";
    },
    _setup: function () {
      if (this._loadingTextNode) {
        var loadingText = UES.localize("ues_v5.core_v1.appc_v1.visc_v1.pagecomponents.Progress_TEXT");
        this._loadingTextNode.appendChild(document.createTextNode(loadingText));
      }

      // FIXME We should set width to the containerNode. For the time being,
      // we set width to the DOM node, because on containerNode it gets
      // reset by Dojo. We could set minWidth to override Dojo's setting, but
      // that doesn't work in IE6.
      if (this.width != "auto") {
        var widthForContent = this.width;
        if (this.width.match(/px$/)) {
          // add container's box padding & border & margin to the width
          widthForContent = parseFloat(this.width) + (dojo.marginBox(this.containerNode).w - dojo.contentBox(this.containerNode).w) + "px";
        }
        if (this.showLoading) this._loadingOrigWidth = widthForContent;
        else this.domNode.style.width = widthForContent;
      }

      // adopt .uc-title if it's present
      // FIXME Use this.title in a standard way (instead of this._uesTitle).
      var uesTitle = dojo.query(".uc-title", this.containerNode)[0];
      if (uesTitle) {
        this.title = uesTitle.innerHTML;
        uesTitle.parentNode.removeChild(uesTitle);
      }
      if (this.title) {
        dojo.addClass(this.titleBar, "ues-core-webui-dialog_staticBar");
        dojo.addClass(this.titleNode, "uc-title");
        this.titleNode.innerHTML = this.title;
        this._uesTitle = this.title;
        this.title = null;
      }

      // add title icon (if any)
      if (this._uesTitle && this.titleIcon) {
        // TODO Implement
        var img = document.createElement("img");
        img.src = this.titleIcon;
        this.titleNode.appendChild(img);
        dojo.addClass(this.titleBar, "ues-core-webui-dialog_titleWithIcon");
      }

      // call superclass with disabled draggable support (we're using
      // our own drag handle)
      var origDraggable = this.draggable;
      this.draggable = false;
      this.inherited(arguments);
      this.draggable = origDraggable;

      // add drag / resize widgets and initialize other properties before showing
      if (this.draggable) this._handleDraggableAttrChange();
      if (this.resizeY) this._handleResizeAttrChange();
      if (this.shadow) this._handleShadowAttrChange();
      this.attr("_active", true);

      // configure underlay
      this.underlayAttrs.id = this.id + "_underlayWrapper";
      if (!this.underlay) {
        if (dijit._dialogStack.length > 0) {
          // use underlayAttrs from the window below (i.e. let the display be
          // exactly the same as before opening the window)
          this.underlayAttrs = dojo.mixin({}, dijit._dialogStack[dijit._dialogStack.length-1].underlayAttrs);
          // this resets z-index of the underlay to the previous level
          // (for cases when we don't want this dialog to show an underlay)
          // FIXME Do somehow better?
          this.connect(this._fadeIn, "beforeBegin", function () {
            var zIndex = 948 + (dijit._dialogStack.length-1)*2;
            dojo.style(dijit._underlay.domNode, 'zIndex', zIndex);
          });
        } else {
          // hide the underlay
          this.underlayAttrs["class"] += " hidden";
        }
      }

      // add connects
      this.connect(this._fadeOut, "onEnd", "onHideEnd");
    },
    _setDragHandlePosition: function () {
    },
    _setDraggableAttr: function (aValue) {
      if (UES.isHandheld) aValue = false;
      if (this.draggable === aValue) return;

      this.draggable = aValue;
      this._handleDraggableAttrChange();
    },
    _handleDraggableAttrChange: function () {
      if (this.draggable) {
        // add drag support
        var dragHandle = dojo.doc.createElement("div");
        dojo.addClass(dragHandle, this.dragHandleClass);
        dojo.place(dragHandle, this.domNode);
        var that = this;
        this._moveable = new dojo.dnd.move.constrainedMoveable(this.domNode, {
          handle: dragHandle,
          within: true,
          constraints: function () {
            var box = dijit.getViewport();
            box.h += that.domNode.offsetHeight - (dragHandle.offsetHeight || 37) - 8;
            return box;
          },
          mover: ues.core.webui._DialogMover
        });
        this._dragSubscribes.push(this.subscribe("/dnd/move/stop", "_endDrag"));
        this._dragConnects.push(this.connect(this._moveable, "onMoveStart", "_dragStart"));
        this._dragConnects.push(this.connect(this._moveable, "onMoveStop", "_dragStop"));
        dojo.removeClass(this.domNode, "dijitDialogFixed");
        this._setDragHandlePosition();
      } else {
        // remove drag support
        dojo.query("> ."+this.dragHandleClass, this.domNode).orphan();
        var that = this;
        dojo.forEach(this._dragConnects, function (aConnect) { that.disconnect(aConnect); });
        dojo.forEach(this._dragSubscribes, function (aSub) { that.unsubscribe(aSub); });
        this._dragConnects = [];
        this._dragSubscribes = [];
        dojo.addClass(this.domNode, "dijitDialogFixed");
      }
    },
    _setResizeYAttr: function (aValue) {
      if (UES.isHandheld) aValue = false;
      if (this.resizeY === aValue) return;

      this.resizeY = aValue;
      this._handleResizeAttrChange();
    },
    _handleResizeAttrChange: function () {
      if (this.resizeY) {
        // add resize handle
        this.resizeHandle = new dojox.layout.ResizeHandle({
          targetId: this.id,
          resizeAxis: "y",
          activeResize: false,
          animateSizing: false,
          minHeight: this.minHeight,
          startTopic: "/ues/base/dialog/resize/start",
          endTopic: "/ues/base/dialog/resize/stop"
        }).placeAt(this.domNode);
        this._resizeConnects.push(this.connect(this.resizeHandle, "onResize", "onResize"));
        this._resizeSubscribes.push(this.subscribe(this.resizeHandle.startTopic, "_resizeStart"));
        this._resizeSubscribes.push(this.subscribe(this.resizeHandle.endTopic, "_resizeStop"));
      } else {
        // remove resize handle
        this.resizeHandle.destroyRecursive();
        this.resizeHandle = null;
        var that = this;
        dojo.forEach(this._resizeConnects, function (aConnect) { that.disconnect(aConnect); });
        dojo.forEach(this._resizeSubscribes, function (aSub) { that.unsubscribe(aSub); });
        this._resizeConnects = [];
        this._resizeSubscribes = [];
      }
    },
    _setShadowAttr: function (aValue) {
      if (this.shadow === aValue) return;
      this.shadow = !!aValue;
      this._handleShadowAttrChange();
    },
    _handleShadowAttrChange: function () {
      if (this.shadow) dojo.addClass(this.domNode, CSS_BOX_SHADOW);
      else dojo.removeClass(this.domNode, CSS_BOX_SHADOW);
    },
    _set_activeAttr: function (aValue) {
      this._active = aValue;
      if (!this._active) dojo.addClass(this.domNode, "ues-core-webui-dialog_inactive");
      else dojo.removeClass(this.domNode, "ues-core-webui-dialog_inactive");
    },
    onResize: function () {
      // empty stub
    },
    _dragStart: function () {
      // add transparent layer over iframe, otherwise the iframe would capture mousemove events (Dojo #7210)
      this._dragLayer = new dijit.layout.ContentPane({"class": "transparent-layer", style: "z-index: 1000; cursor: move;"});
      this._dragLayer.placeAt(dojo.body());
    },
    _dragStop: function () {
      if (!this._dragLayer) return;
      this._dragLayer.destroyRecursive();
      this._dragLayer = null;
    },
    _resizeStart: function (aResizeHandle) {
      if (aResizeHandle !== this.resizeHandle) return;

      // add transparent layer over iframe, otherwise the iframe would capture mousemove events (Dojo #7210)
      var axis = this.resizeHandle.attr("resizeAxis");
      var cursor = (axis == "y" || axis == "xy" ? "n" : "");
      cursor += (axis == "x" || axis == "xy" ? "w" : "");
      cursor = cursor || "n";
      this._resizeLayer = new dijit.layout.ContentPane({"class": "transparent-layer", style: "z-index: 1000; cursor: " + cursor + "-resize;"});
      this._resizeLayer.placeAt(dojo.body());
    },
    _resizeStop: function (aResizeHandle) {
      if (aResizeHandle !== this.resizeHandle || !this._resizeLayer) return;
      this._resizeLayer.destroyRecursive();
      this._resizeLayer = null;
    },
    _setMinHeightAttr: function (aValue) {
      this.minHeight = aValue;
      if (this.resizeHandle) {
        this.resizeHandle.attr("minHeight", aValue);
        if (typeof this.resizeHandle.minSize == "object") this.resizeHandle.minSize.h = aValue; // FIXME Remove this hack.
      }
    },
    show: function () {
      dojo.addClass(dojo.body(), "ues-core-webui-dialog_shown");

      this.inherited(arguments);
      if (this._uesTitle) {
        this._prevTitle = window.titleUC;
        window.titleUC = this._uesTitle;
        getBaseWindow().setTitle();
      }

      // remove listeners for window resize / scroll
      if (!this.autoPosition) {
        // TODO Do in a safer way?
        dojo.disconnect(this._modalconnects[0]);
        dojo.disconnect(this._modalconnects[1]);
        this._modalconnects = this._modalconnects.slice(2);
      }
    },
    hide: function () {
      this.inherited(arguments);
      if (this._uesTitle) {
        window.titleUC = this._prevTitle;
        getBaseWindow().setTitle();
      }
      if (dijit._dialogStack.length == 0) dojo.removeClass(dojo.body(), "ues-core-webui-dialog_shown");
    },
    onHideEnd: function () {
      // "connect" for case that the dialog is fully hidden (closing animation
      // is finished)
    },
    uninitialize: function () {
      // TODO According to http://higginsforpresident.net/2010/01/widgets-within-widgets/
      // this might not be the best way (even though it's working).
      if (!this._supportingWidgets) this._supportingWidgets = [];

      // handle case when we're being destroyed during resize
      if (this._resizeLayer) this._supportingWidgets.push(this._resizeLayer);
      this._resizeLayer = null;

      // handle case when we're being destroyed during drag
      if (this._dragLayer) this._supportingWidgets.push(this._dragLayer);
      this._dragLayer = null;

      // destroy resizeHandle as well because it's outside of containerNode
      if (this.resizeHandle) this._supportingWidgets.push(this.resizeHandle);

      this.inherited(arguments);
    },
    _onKey : function(e) {
      // if it's control sequence or non-printable then let it bubble
    	if (e.ctrlKey || e.altKey || e.metaKey) return;
    	if (!e.charCode && e.charOrCode != dojo.keys.TAB && e.charOrCode != dojo.keys.ESCAPE) return;

    	// ues Dojo's dialog key handling (Tab, Escape, printable chars)
    	this.inherited(arguments);
		},
		_position : function() {
			if (!dojo.hasClass(dojo.body(), "dojoMove")) {
				var n = this.domNode;
				var _vp = dijit.getViewport();
				var bb = dojo._getBorderBox(n);
				var l = Math.floor(_vp.l + (_vp.w - bb.w) / 2), t = Math.floor(_vp.t + (_vp.h - bb.h) / 2);
				dojo.style(n, {
					left : l + "px",
					top : t + "px"
				});
			}
    },

    _setShowLoadingAttr: function (aValue) {
      if (!this._loadingTextNode) return;
      if (this.showLoading == aValue) return;
      this.showLoading = aValue;
      // display / hide loading message
      if (this.showLoading) {
        this._loadingOrigWidth = this.domNode.style.width;
        dojo.addClass(this.domNode, "ues-core-webui-dialog_loading");
        this.domNode.style.width = "auto";
      } else {
        this.domNode.style.width = this._loadingOrigWidth;
        dojo.removeClass(this.domNode, "ues-core-webui-dialog_loading");
      }
      this._position();
    }
  });

  /** Localization pack. */
  var LOC = dojo.i18n.getLocalization("ues.core.webui", "dialog");

  /**
   * Base class for dialogs with button bar.
   */
  var BD = dojo.declare("ues.core.webui.ButtonDialog", ues.core.webui.Dialog, {
    /**
     * An array of button definitions, e.g.
     * <code>[{name:"btnSearch", label:"...", "default": true}, {name:"ok"}, "cancel"]</code>
     * Buttons with names "ok", "cancel" can be given as an item in the form of
     * a simple string (see example above) and also without label.
     */
    buttons: null,
    /** The node containing buttons. */
    buttonBarNode: null,
    _buttonWidgets: null,
    autofocus: true,

    _setup: function () {
      this.buttonBarNode = dojo.create("div", { "class": "ues-core-webui-dialog_buttonBar" }, this.domNode);

      // initialize buttons
      this._initButtons();

      // call super logic
      this.inherited(arguments);
    },
    _initButtons: function () {
      // create buttons
      dojo.forEach(this.buttons, function (aItem) {
        var btnDef = { "default": false };
        if (typeof aItem == "string") btnDef.name = aItem;
        else dojo.mixin(btnDef, aItem);
        if (!btnDef.label) {
          switch (btnDef.name) {
          case "ok":
            dojo.mixin(btnDef, { label: this.buttonOk });
            break;
          case "cancel":
            dojo.mixin(btnDef, { label: this.buttonCancel });
            break;
          case "yes":
            dojo.mixin(btnDef, { label: LOC.buttonYes });
            break;
          case "no":
            dojo.mixin(btnDef, { label: LOC.buttonNo });
            break;
          }
        }
        // create the button
        if (btnDef.name && btnDef.label) this._initButton(btnDef);
      }, this);
    },
    _initButton: function (aButtonDef) {
      if (!this._buttonWidgets) this._buttonWidgets = [];
      var btnParams = dojo.mixin({}, aButtonDef);
      delete btnParams.name;
      var btn = new ues.core.webui.form.Button(btnParams);
      this.connect(btn, "onClick", function () { this._onButtonClick(aButtonDef.name); });
      this._buttonWidgets.push(btn);
      btn.placeAt(this.buttonBarNode);
    },

    _onButtonClick: function (aButton) {
      var context = { buttonName: aButton, closeDialog: true };
      this.onButton(context);
      if (context.closeDialog) this.hide();
    },
//    _onButton: function (aButton) {
//      return false;
//    },
    /**
     * @param aButtonContext Structure with following attributes:<ul>
     *                       <li>buttonName - button name
     *                       <li>closeDialog - settable flag for indication whether to
     *                                         close the dialog after the click. Default
     *                                         is true.
     *                       </ul>
     */
    onButton: function (aButtonContext) {
      // "connect" for arbitrary button click
    },

    uninitialize: function () {
      // destroy buttons
      for (var i=0; i<this._buttonWidgets.length; ++i) {
        this._buttonWidgets[i].destroyRecursive();
      }
      this.inherited(arguments);
    }
  });
  BD.BTN_OK = "ok";
  BD.BTN_CANCEL = "cancel";
  BD.BTN_YES = "yes";
  BD.BTN_NO = "no";

  // FIXME Message dialogs should be automatically destroyed after
  // they are closed.
  /**
   * Base class for dialogs with icon in the title displaying simple message
   * (e.g. error dialog, information dialog, ...).
   */
  var MD = dojo.declare("ues.core.webui.MessageDialog", BD, {
    /** The text message to show in the dialog. */
    message: "",
    width: "432px",
    resizeY: false, // FIXME This shall be "resizable: false" when "resizable" gets implemented.

    _setup: function () {
      // set the content
      if (this.message) dojo.place(document.createTextNode(this.message), this.containerNode, "only");

      // update visual styles
      dojo.addClass(this.domNode, "ues-core-webui-messageDialog");
      // FIXME Remove and style properly.
      dojo.addClass(this.titleNode, "S000105title");
      dojo.addClass(this.containerNode, "S000105desc");

      // call super logic
      this.inherited(arguments);
    }
  });


  var ICON_ERROR = UES.Util.getRealImagePath("/images/other/dialog_error.gif");
  var ICON_INFO = UES.Util.getRealImagePath("/images/other/dialog_information.gif");
  var ICON_WARNING = UES.Util.getRealImagePath("/images/other/dialog_warning.gif");
  var ICON_QUESTION = UES.Util.getRealImagePath("/images/other/dialog_question.gif");

  dojo.declare("ues.core.webui.ErrorDialog", ues.core.webui.MessageDialog, {
    title: LOC.error,
    titleIcon: ICON_ERROR,
    buttons: ["ok"]
  });
  dojo.declare("ues.core.webui.InformationDialog", ues.core.webui.MessageDialog, {
    title: LOC.information,
    titleIcon: ICON_INFO,
    buttons: ["ok"]
  });
  dojo.declare("ues.core.webui.WarningDialog", ues.core.webui.MessageDialog, {
    title: LOC.warning,
    titleIcon: ICON_WARNING,
    buttons: ["ok"]
  });
  dojo.declare("ues.core.webui.ConfirmationDialog", ues.core.webui.MessageDialog, {
    title: LOC.confirmation,
    titleIcon: ICON_QUESTION,
    buttons: ["yes", "no"]
  });

  // add preloading of dialog icons
  dojo.addOnLoad(function () {
    dojox.image.preload([ICON_ERROR, ICON_INFO, ICON_WARNING, ICON_QUESTION]);
  });



  // FIXME If user calls #open() and then #abort(),
  // dialog's "onHide" event might or might not be triggerred - this probably
  // isn't good behaviour...
  /**
   * Simple class for delaying dialog opening. User can set delay, during which
   * user interface is blocked and after that the dialog's loading message is shown.
   * In order to show the real contents of the dialog, the user must execute
   * #setLoaded() function. User can also execute #abort() instead of #setLoaded() in
   * which case the dialog stops opening / loading message gets hidden.
   * <p>Note that the delay might end sooner (and dialog's loading message might be
   * entirely skipped) if the #setLoaded() method gets executed sooner than the specified delay.
   * */
  dojo.declare("ues.core.webui.DialogOpener", null, {
    dialog: null,
    delay: 2000,
    _connects: null,
    _uiConnects: null,
    _layerID: TRANSPARENT_LAYER,
    _state: null,
    S: {
      INIT: 0,
      OPENING: 1, // the dialog is being open (nothing is shown yet, i.e. we're in the time-frame of delay)
      LOADING: 2 // the dialog is shown with "Loading..." message
    },
    constructor: function (aParams) {
      this._connects = [];
      this._uiConnects = [];
      this._state = this.S.INIT;
      if (aParams) dojo.mixin(this, aParams);
    },
    open: function () {
      function showDialog() {
        that._state = that.S.LOADING;
        that._unblockUI();
        that.dialog.attr("showLoading", true);
        that.dialog.show();
      }
      var that = this;
      if (this._state > this.S.INIT) this._cleanup();
      this._state = this.S.OPENING;

      dojo.connect(this.dialog, "onHide", this, "_dialogClosed");
      if (this.delay <= 0) {
        showDialog();
        return;
      }

      // plan displaying of the dialog's Loading... message after the delay
      this._firstInfoTimeout = setTimeout(function () {
        delete that._firstInfoTimeout;
        showDialog();
      }, this.delay);

      // block UI (clicks & keys)
      this._blockUI();
    },
    setLoaded: function () {
      switch (this._state) {
      case this.S.INIT: break;
      case this.S.OPENING:
        clearTimeout(this._firstInfoTimeout);
        delete this._firstInfoTimeout;
        this._cleanup();
        this.dialog.show();
        this._state = this.S.INIT;
        break;
      case this.S.LOADING:
        this.dialog.attr("showLoading", false);
        this._cleanup();
        this._state = this.S.INIT;
        break;
      }
    },
    abort: function () {
      switch (this._state) {
      case this.S.INIT: break;
      case this.S.OPENING:
        this._cleanup();
        this._state = this.S.INIT;
        break;
      case this.S.LOADING:
        this.dialog.hide();
        this._cleanup();
        this._state = this.S.INIT;
        break;
      }
    },
    _dialogClosed: function () {
      if (this._state != this.S.INIT) this._cleanup();
      this._state = this.S.INIT;
    },

    _blockUI: function () {
      var overlay = UES.$(this._layerID);
      var level = dijit._dialogStack.length + 1;
      if (!overlay) UES.Util.DOM.createLayer(level, { id: this._layerID });
      else UES.Util.DOM.moveLayer(overlay, level);
      this._uiConnects.push(dojo.connect(document, "onkeydown", null, dojo.stopEvent));
      this._uiConnects.push(dojo.connect(document, "onkeypress", null, dojo.stopEvent));
    },
    _cleanup: function () {
      // unblock UI & remove all connects
      this._unblockUI();
      dojo.forEach(this._connects, dojo.disconnect);
      this._connects = [];
      if (this._firstInfoTimeout) {
        clearTimeout(this._firstInfoTimeout);
        delete this._firstInfoTimeout;
      }
    },
    _unblockUI: function () {
      if (this._uiConnects.length == 0) return;
      UES.Util.DOM.removeLayer(this._layerID);
      dojo.forEach(this._uiConnects, dojo.disconnect);
      this._uiConnects = [];
    }
  });

  })();
}

