dojo.provide("parus.dialog");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit.Dialog");
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.Select");
dojo.require("dojox.layout.ResizeHandle");

dojo.declare("parus.Dialog", [dijit._Widget, dijit._TemplatedMixin], {

  widgetsInTemplate: false,

  destroyOnClose: true,

  dialog: null,

  title: null,

  applied: false,

  sizeable: "xy",

  autoSize: false,
  //default size would be calculated from this.getDefaultAutoSize()
  defaultUserSize: null,
  //specified default size - example:
  /*defaultUserSize: {
   width: "60%",
   height: "70%"
   },*/
  userSize: null,
  //saved user size
  userSizeDataSection: null,

  style: "display:none",

  applyProgressLabel: null,

  postMixInProperties: function() {
    this.inherited(arguments);

    //to be overridden in descendants
    if (!this.templateString) {
      var names = this.declaredClass.split(".");
      this.templateString = dojo.cache(dojo.moduleUrl(names[0], names[1] + ".html"));
    }

    this.userSizeDataSection = this.declaredClass + "-userSize";
  },

  postCreate: function() {
    this.inherited(arguments);

    if (dojo.isIE >= 10) dojo.query("*[gutters='true']", this.domNode).forEach(function(node) {
      node.setAttribute("gutters", "false");
      dojo.addClass(node, "dialogContentPaneColor");
      for (var i = 0; i < node.childNodes.length; i++)
      if (node.childNodes[i]) if (node.childNodes[i].style) node.childNodes[i].style.margin = "5px";
    });

    var parsed = dojo.parser.parse({
      rootNode: this.domNode,
      template: true
    });

    dojo.mixin(this, {
      dialog: parsed[0]
    });

    if (!this.dialog) throw new Error("Dialog element is not defined for class " + this.declaredClass + ".");

    this.dialog.domNode.style.top = "-1800px";
    this.dialog.containerNode.style.padding = "0";
    dojo.connect(this.dialog, "onCancel", this, "close");

    dojo.mixin(this.dialog, {
      _position: dojo.hitch(this.dialog, this.__positionDialog),
      _size: dojo.hitch(this.dialog, this.__sizeDialog)
      //      resize: dojo.hitch(this.dialog, this.__sizeDialog)
    });

    if (this.title) this.dialog.titleNode.innerHTML = this.title;

    dojo.forEach(parsed, dojo.hitch(this, function(widget) {
      dojo.mixin(widget, {
        dialogObject: this,
        dialog: this.dialog
      });
      var attachPoint = widget.dojoAttachPoint;
      if (attachPoint && (dojo.indexOf(this._attachPoints, attachPoint) != -1)) this[attachPoint] = widget;
    }));

    var oldHandler = dojo.hitch(this.dialog, this.dialog._onKey);

    dojo.mixin(this.dialog, {
      _onKey: dojo.hitch(this, function(evt) {
        oldHandler(evt);
        if ((evt.keyCode == 13) && (evt.target.nodeName !== "TEXTAREA")) {
          dijit.focus(this.dialog.domNode);
          this.apply();
        }
      })
    });

    this.onLoad(this);
  },

  //to be overridden
  getDefaultAutoSize: function() {
    var viewport = dojo.window.getBox();
    return {
      width: (viewport.w * 0.8) + "px",
      height: (viewport.h * 0.8) + "px"
    };
  },

  isPercentValue: function(value) {
    return value && (typeof value == "string") && value.endsWith("%");
  },

  userSizeFromPercentToPixels: function(value) {
    if (this.isPercentValue(value.width) || this.isPercentValue(value.height)) {
      var viewport = dojo.window.getBox();

      if (this.isPercentValue(value.width)) value.width = (viewport.w * (parseInt(value.width) / 100)) + "px";
      if (this.isPercentValue(value.height)) value.height = (viewport.h * (parseInt(value.height) / 100)) + "px";
    }
    return value;
  },

  show: function() {
    if (this.sizeable) {
      this.userSize = parus.userdata.get(this.userSizeDataSection) || this.userSize;
      if (!this.userSize.height && !this.userSize.width && this.autoSize) if (!this.defaultUserSize) this.defaultUserSize = this.getDefaultAutoSize();
    };

    this._onShow();
    this.validate();
    if (dijit._masterTT) if (dijit._masterTT.isShowingNow) dijit.hideTooltip(dijit._masterTT.aroundNode);
    var result = (new dojo.DeferredList([this.dialog.show()]));

    if (this.dialog._singleChild) {

      var cn = dojo.getMarginSize(this.dialog._singleChild.domNode);

      dojo.style(this.dialog._singleChild.domNode, {
        minWidth: cn.w,
        minHeight: cn.h
      });

    }
    else {

      var cn = dojo.getMarginSize(this.dialog.containerNode);

      dojo.style(this.dialog.containerNode, {
        minWidth: cn.w,
        minHeight: cn.h
      });

    }

    if (this.sizeable) this._startupResize();
    return result;
  },

  close: function() {
    if (this.sizeable) {
      parus.userdata.set(this.userSizeDataSection, this.userSize);
    };

    if (this.dialog.open)(new dojo.DeferredList([this.dialog.hide()])).addCallback(
    dojo.hitch(this, function(result) {
      this._onClose();
      if (this.destroyOnClose) {
        this.dialog.destroyRecursive();
        this.dialog = null;
        this.destroyRecursive();
        return result;
      }
    }))
    else {
      this._onClose();
      if (this.destroyOnClose) {
        this.dialog.destroyRecursive();
        this.dialog = null;
        this.destroyRecursive();
      }
    }
  },

  validate: function() {
    return (!this.dialog || this.dialog.validate())
  },

  apply: function() {
    if (!this.validate()) return;

    if (this.applyProgressLabel) {

      var f = dojo.hitch(this, function() {

        var progressIndicator = new parus.progressDialog({
          message: this.applyProgressLabel
        });
        progressIndicator.show().addCallback(

        dojo.hitch(this, function() {

          try {
            this.applied = this.onApply(this);
          }
          catch (e) {

            this.applied = false;

          }

          progressIndicator.close();
          progressIndicator.destroyRecursive();

          if (this.applied) this.close()

        }));

      });

      if (this.dialog.open)(new dojo.DeferredList([this.dialog.hide()])).addCallback(f)
      else f();

    }

    else {
      this.applied = this.onApply(this);
      if (this.applied) this.close()
    }
  },

  onLoad: function() {

  },

  onApply: function(dialog) {
    return true;
  },

  //for override by callback
  onShow: function(dialog) {

  },

  //for inherited
  _onShow: function() {
    this.onShow(this);
  },

  //for override by callback
  onClose: function(dialog) {

  },

  //for inherited
  _onClose: function() {
    this.onClose(this);
  },

  helpButtonClick: function() {
    parus.balance.showHelp(this.declaredClass);
  },

  _sizeDifferences: null,

  _startupResize: function() {

    var c = dojo.getMarginSize(this.dialog.domNode);
    var cn = dojo.getMarginSize(this.dialog.containerNode);

    if ( !! !c.w && !! !c.h && !! !cn.w && !! !cn.h) return;

    this._sizeDifferences = {
      dh: c.h - cn.h,
      dw: c.w - cn.w
    };

    if (this.userSize || this.defaultUserSize) {
      var size = this.userSize;
      if (!this.userSize.height && !this.userSize.width && this.defaultUserSize) size = this.userSizeFromPercentToPixels(this.defaultUserSize);

      dojo.style(this.dialog.domNode, {
        width: (parseInt(size.width) + this._sizeDifferences.dw) + "px",
        height: (parseInt(size.height) + this._sizeDifferences.dh) + "px"
      });
      this._onResize(false);
      this.dialog.resize();
      this.dialog._position();
    }

    var rzNode = document.createElement("div");
    this.dialog.domNode.appendChild(rzNode);

    this._resizeHandle = new dojox.layout.ResizeHandle({
      targetId: this.dialog.id,
      resizeAxis: this.sizeable,
      activeResize: true,
      animateSizing: true,
      intermediateChanges: false,
      minHeight: cn.h,
      minWidth: cn.w,
      onResize: dojo.hitch(this, function() {
        setTimeout(dojo.hitch(this, function() {
          this._onResize(true);
        }), 1);
      })
    }, rzNode);

    this._resizeHandle.startup();

  },


  _resizeHandle: null,

  _onResize: function(saveSize) {

    var c = dojo._getMarginSize(this.dialog.domNode);

    if ( !! !c.w && !! !c.h) return;

    if (saveSize) this.userSize = {
      height: this.dialog.domNode.style.height,
      width: this.dialog.domNode.style.width
    };

    dojo.style(this.dialog.containerNode, {
      height: (c.h - this._sizeDifferences.dh) + "px",
      width: (c.w - this._sizeDifferences.dw) + "px"
    });

    this._resizeChildren();
  },

  _resizeChildren: function() {
    var widgets = [];

    for (var i = 0; i < this.dialog.containerNode.childNodes.length; i++) {
      var node = this.dialog.containerNode.childNodes[i];
      if (node.style) {
        dojo.style(node, {
          minHeight: this.dialog.containerNode.clientHeight,
          minWidth: this.dialog.containerNode.clientWidth
        });
        var widget = dijit.byNode(node);
        if (widget && widget.layout) widgets.push(widget);
      }
    };

    if (widgets.length) dojo.forEach(widgets, function(widget) {
      widget.resize();
    });
  },

  __sizeDialog: function() {

    if (!this.dialogObject.sizeable) return;

    this._checkIfSingleChild();

    if (this._singleChild) {

      if (this._singleChildOriginalStyle) {
        this._singleChild.domNode.style.cssText = this._singleChildOriginalStyle || "";
      }
      delete this._singleChildOriginalStyle;
    } else {
      dojo.style(this.containerNode, {
        width: "auto",
        height: "auto"
      });
    };

    var z = dojo.isIE ? 1 : parus.parus8.getZoom();
    var mb = dojo._getMarginSize(this.domNode);
    var viewport = dojo.window.getBox();
    var cn = dojo._getMarginSize((this._singleChild ? this._singleChild.domNode : null) || this.containerNode);

    viewport.w = viewport.w - (mb.w - cn.w) * z - 3;
    viewport.h = viewport.h - (mb.h - cn.h) * z - 3;


    if (mb.w * z >= viewport.w || mb.h * z >= viewport.h) {

      var w = Math.min(mb.w * z, Math.floor(viewport.w)),
          h = Math.min(mb.h * z, Math.floor(viewport.h));

      if (this._singleChild && this._singleChild.resize) {
        this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText;
        this._singleChild.resize({
          w: w / z,
          h: h / z
        });

      } else {
        dojo.style(this.containerNode, {
          width: (w / z) + "px",
          height: (h / z) + "px"
        });
      }
    } else {
      if (this._singleChild && this._singleChild.resize) {
        this._singleChild.resize();
      }
    }
  },

  __positionDialog: function() {
    if (!dojo.hasClass(dojo.body(), "dojoMove")) {

      var node = this.domNode,
          z = dojo.isIE ? 1 : parus.parus8.getZoom(),
          viewport = dojo.window.getBox(),
          p = this._relativePosition,
          bb = p ? null : dojo.marginBox(node),
          l = Math.floor(viewport.l + (p ? p.x : (viewport.w - bb.w * z) / 2)),
          t = Math.floor(viewport.t + (p ? p.y : (viewport.h - bb.h * z) / 2));

      if (!dojo.isOpera && !dojo.getComputedStyle(dojo.body()).zoom) z = 1;

      if (!bb) return;
      if ( !! !bb.l && !! !bb.t && !! !bb.w && !! !bb.h) return;

      dojo.style(node, {
        left: (l / z) + "px",
        top: (t / z) + "px"
      });
    }
  },

  _activateResize: function() {

    if (this.sizeable && !this._resizeHandle && (dijit.Dialog._dialogStack[dijit.Dialog._dialogStack.length - 1].dialog.id == this.dialog.id)) {

      this.userSize = parus.userdata.get(this.userSizeDataSection) || this.userSize;
      if (!this.userSize.height && !this.userSize.width && this.autoSize) if (!this.defaultUserSize) this.defaultUserSize = this.getDefaultAutoSize();

      this.dialog._position();
      this.dialog._size();
      this._startupResize();
      this._onResize(false);

    }
  }


});


dojo.declare("parus.messageDialog", [parus.Dialog], {

  message: null,

  sizeable: null,

  _additionalHeight: null,

  postCreate: function() {
    this.inherited(arguments);
    this.messageText.innerHTML = this.message;
  },

  _activateResize: function() {
    this._place();
  },

  onShow: function() {
    this._place();
  },

  _place: function() {
    setTimeout(dojo.hitch(this, function() {

      dojo.style(this.dialog.containerNode, {
        minWidth: "",
        minHeight: "",
        backgroundColor: dojo.getComputedStyle(dojo.query("*[class]", this.dialog.containerNode)[0]).backgroundColor
      });


      var c = dojo.getMarginSize(this.dialog.domNode);
      var cn = dojo.getMarginSize(this.dialog.containerNode);
      var tn = dojo._getMarginSize(this.messageText);

      this._sizeDifferences = {
        dh: c.h - cn.h,
        dw: c.w - cn.w
      };

      if (tn.w < 310) {
        tn.w = 310;
      }
      tn.h = tn.h + (this._additionalHeight || 0);

      this._onResize(false);

      this.dialog.domNode.style.width = (tn.w + 70 + this._sizeDifferences.dw) + "px";
      this.dialog.domNode.style.height = (tn.h + 70 + this._sizeDifferences.dh) + "px";

      this.dialog.containerNode.style.width = (tn.w + 70) + "px";
      this.dialog.containerNode.style.height = (tn.h + 70) + "px";

      this.dialog.resize();
      this.dialog.containerNode.style.overflowX = "hidden";
      this.dialog._position();

    }), 100);


  }


});