// Copyright (c) 2006 spinelz.org (http://script.spinelz.org/)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var Window = Class.create();
Window.className = {
  window : 'window',
  header : 'window_header',
  headerLeft : 'window_headerLeft',
  headerMiddle : 'window_headerMiddle',
  headerRight : 'window_headerRight',
  buttonHolder : 'window_buttonHolder',
  closeButton : 'window_closeButton',
  maxButton : 'window_maxButton',
  minButton : 'window_minButton',
  body : 'window_body',
  bodyLeft : 'window_bodyLeft',
  bodyMiddle : 'window_bodyMiddle',
  bodyRight : 'window_bodyRight',
  bottom : 'window_bottom',
  bottomLeft : 'window_bottomLeft',
  bottomMiddle : 'window_bottomMiddle',
  bottomRight : 'window_bottomRight',
  mask : 'window_popupMask',
  frame : 'window_frame'
}

Window.modalIdList = new Array();

Window.eventHandler = {

  isOutOfModal: function(srcElement) {
    var length = Window.modalIdList.length;
    var currentModalId = Window.modalIdList[length-1];
    if (length > 0){
      
      while ((srcElement = srcElement.parentNode) && srcElement != document.body) {
        if ((srcElement.id && srcElement.id == currentModalId)
           || srcElement.style && (srcElement.style.zIndex > $(currentModalId+"_mask").style.zIndex)
           ) {
          return true;
        }
      }
    } else if (length == 0) {
      return true;
    }
    return false;
  },

  focusCurrentModal: function() {
    var length = Window.modalIdList.length;
    var currentModalId = Window.modalIdList[length-1];
    var forms = $(currentModalId).getElementsByTagName('form');
    if (forms && forms.length > 0) {
      Form.focusFirstElement(forms[0]);
    }
  },

  handleEvent: function (ev) {
    if(document.all) {
      ev = event;
    }
    var src = Event.element(ev);
    if (!Window.eventHandler.isOutOfModal(src)) {
      Event.stop(ev);
      Window.eventHandler.focusCurrentModal();
    }
  }
}

Window.prototype = {
  
  initialize: function(element) {
    var options = Object.extend({
      className: Window.className.window,
      width: 300,
      height: 300,
      minWidth: 100,
      minHeight: 40,
      drag: true,
      resize: true,
      resizeX: true,
      resizeY:true,
      modal: false,
      closeButton: true,
      maxButton: true,
      minButton: true,
      cssPrefix: 'custom_',
      restriction: false,
      endDrag: Prototype.emptyFunction,
      endResize: Prototype.emptyFunction,
      addButton: Prototype.emptyFunction,
      preMaximize: function() {return true},
      preMinimize: function() {return true},
      preRevertMaximize: function() {return true},
      preRevertMinimize: function() {return true},
      preClose: function() {return true},
      endMaximize: Prototype.emptyFunction,
      endMinimize: Prototype.emptyFunction,
      endRevertMaximize: Prototype.emptyFunction,
      endRevertMinimize: Prototype.emptyFunction,
      endClose: Prototype.emptyFunction
    }, arguments[1] || {});
    
    var customCss = CssUtil.appendPrefix(options.cssPrefix, Window.className);
    this.classNames = new CssUtil([Window.className, customCss]);
    
    this.element = $(element);
    Element.setStyle(this.element, {visibility: 'hidden'});

    this.options = options;
    this.element.className = this.options.className;
    this.header = null;
    this.windowBody = null;
    this.bottom = null;
    
    this.elementId = this.element.id;
    this.dragHandleId = this.elementId + '_dragHandle';
    this.maskId = this.elementId + '_mask';
    this.frameId = this.elementId + '_frame';
    
    this.maskZindex = -1;
    this.maxZindex = -1;
    this.minFlag = false;
    this.maxFlag = false;
    this.currentPos = [0,0];
    this.currentSize = [0,0];
    this.maskSize = [Element.getWindowWidth(), Element.getWindowHeight()];
    this.buildWindow();
    
    if (document.all) this.buildFrame();
    
    Element.makePositioned(element);
    Element.hide(this.element);
    Element.setStyle(this.element, {visibility: 'visible'});
  },

  buildFrame: function() {
    var frame = Builder.node('iframe', {id: this.frameId, frameborder: 0});
    this.classNames.addClassNames(frame, 'frame');

    this.element.insertBefore(frame, this.element.firstChild);
    this.setFrameSize();
  },

  buildWindow: function() {
    Element.cleanWhitespace(this.element);
    
    with(this.element.style) {
      width = this.options.width + 'px';
      height= this.options.height + 'px';
    }

    var title = this.element.childNodes[0];
    var content = this.element.childNodes[1];
    this.buildHeader(title);
    this.buildBody(content);
    this.buildBottom();
    var newStyle = {height: this.options.height};
    this.setBodyHeight(newStyle);

    if (this.options.drag) this.createDraggble();

    if (this.options.resize) {
      this.enableResizing();
    }
  },

  buildHeader: function(title) {
    var headerLeft = Builder.node('div');
    this.classNames.addClassNames(headerLeft, 'headerLeft');

    var headerMiddle = Builder.node('div', {id: this.dragHandleId});
    this.classNames.addClassNames(headerMiddle, 'headerMiddle');
    
    var headerRight = Builder.node('div');
    this.classNames.addClassNames(headerRight, 'headerRight');

    var buttonHolder = Builder.node('div');
    this.classNames.addClassNames(buttonHolder, 'buttonHolder');
    
    headerMiddle.appendChild(title);
    var headerList = [headerLeft, headerMiddle, buttonHolder, headerRight];
    this.header = Builder.node('div', headerList);
    this.classNames.addClassNames(this.header, 'header');
    this.element.appendChild(this.header);
    
        
    if (this.options.closeButton) {
      var closeButton = Builder.node('div', {id: this.element.id.appendSuffix('closeButton')});
      this.classNames.addClassNames(closeButton, 'closeButton');
      buttonHolder.appendChild(closeButton);
      Event.observe(closeButton, 'click', this.close.bindAsEventListener(this));
    }
    if (this.options.maxButton) {
      var maxButton = Builder.node('div', {id: this.element.id.appendSuffix('maxButton')});
      this.classNames.addClassNames(maxButton, 'maxButton');
      buttonHolder.appendChild(maxButton);
      Event.observe(maxButton, 'click', this.maximize.bindAsEventListener(this));
    }
    if (this.options.minButton) {
      var minButton = Builder.node('div', {id: this.element.id.appendSuffix('minButton')});
      this.classNames.addClassNames(minButton, 'minButton');
      buttonHolder.appendChild(minButton);
      Event.observe(minButton, 'click', this.minimize.bindAsEventListener(this));
    }

    if (this.options.addButton) {
      var addButton = this.options.addButton;
      if (addButton.constructor == Function) {
        addButton(buttonHolder);
      } else if (addButton.constructor == Array) {
        var self = this;
        var firstChild = buttonHolder.firstChild;
        addButton.each(function(b) {
          var button = Builder.node('div', {id: b.id, className: b.className});
          Event.observe(button, 'click', b.onclick.bindAsEventListener(self));
          if (b.first && firstChild) {
            buttonHolder.insertBefore(button, firstChild);
          } else {
            buttonHolder.appendChild(button);
          }
        });
      }
    }
  },
  
  buildBody: function(contents) {
    var bodyLeft = Builder.node('div', {className: Window.className.bodyLeft});
    this.classNames.addClassNames(bodyLeft, 'bodyLeft');
    
    var bodyMiddle = Builder.node('div');
    this.classNames.addClassNames(bodyMiddle, 'bodyMiddle');
    bodyMiddle.appendChild(contents);
    
    var bodyRight = Builder.node('div');
    this.classNames.addClassNames(bodyRight, 'bodyRight');

    var bodyList = [bodyRight,bodyLeft, bodyMiddle];
    this.windowBody = Builder.node('div', bodyList);    
    this.classNames.addClassNames(this.windowBody, 'body');
    this.element.appendChild(this.windowBody);
  },
  
  buildBottom: function() {
    
    var bottomLeft = Builder.node('div');
    this.classNames.addClassNames(bottomLeft, 'bottomLeft');
    
    var bottomMiddle = Builder.node('div');
    this.classNames.addClassNames(bottomMiddle, 'bottomMiddle');
    
    var bottomRight = Builder.node('div');
    this.classNames.addClassNames(bottomRight, 'bottomRight');
    
    var bottomList = [bottomLeft, bottomMiddle, bottomRight];
    this.bottom = Builder.node('div', bottomList);
    this.classNames.addClassNames(this.bottom, 'bottom');
    this.element.appendChild(this.bottom);
  },
  
  buildMask: function(zIndex) {
    this.setFullSize(document);

    if (!$(this.maskId)) {
      var mask = Builder.node('div', {id: this.maskId});
      this.classNames.addClassNames(mask, 'mask');      
      document.body.appendChild(mask);
      Window.modalIdList.push(this.element.id);
    }
    this.setMaskZindex(zIndex);
    with ($(this.maskId).style) {
      display = 'block';
      width = this.maskSize[0] + 'px';
      height = this.maskSize[1] + 'px';
    }
    
    
    if (Window.modalIdList.length == 1) {  
      
      Event.observe(document, "keypress", Window.eventHandler.handleEvent.bindAsEventListener(this));
      Event.observe(document, "keydown", Window.eventHandler.handleEvent.bindAsEventListener(this));
      Event.observe(document, "keyup", Window.eventHandler.handleEvent.bindAsEventListener(this));
      Event.observe(document, "focus", Window.eventHandler.handleEvent.bindAsEventListener(this));
      
    }
  },

  createDraggble: function() {
    var self = this;
    var options = {
      handle:      this.dragHandleId,
      startEffect: Prototype.emptyFunction,
      endEffect:   Prototype.emptyFunction,
      endDrag:     this.options.endDrag,
      scroll:      window
    };

    if (this.options.restriction) {
      options.snap = function(x, y) {
        function constrain(n, lower, upper) {
          if (n > upper) return upper; 
          else if (n < lower) return lower;
          else return n;
        }

        var eDimensions = Element.getDimensions(self.element);
        var pDimensions = Element.getDimensions(self.element.parentNode);
        var offset = Position.positionedOffset(self.element.parentNode);
        var parentLeft = offset[0];
        var parentTop = offset[1];

        if (Element.getStyle(self.element.parentNode, 'position') == 'static') {
          return[
            constrain(x, parentLeft, parentLeft + pDimensions.width - eDimensions.width),
            constrain(y, parentTop, parentTop + pDimensions.height - eDimensions.height)
          ];
        } else {
          return[
            constrain(x, 0, pDimensions.width - eDimensions.width),
            constrain(y, 0, pDimensions.height - eDimensions.height)
          ];
        }
      }
    } else {
      options.snap = function(x, y) {
        return [(x > 0) ? x : 0, (y > 0) ? y : 0];
      }
    }
    new DraggableWindowEx(this.element, options);
  },
  
  setFrameSize: function() {
    var frame = $(this.frameId);
    if (frame) {
      var height = Element.getHeight(this.element);
      var width = this.element.offsetWidth;

      frame.width = width;
      frame.height = height;
    }
  },

  setWindowZindex : function(zIndex) {
    zIndex = this.getZindex(zIndex);
    this.element.style.zIndex = zIndex;
    this.currentZindex = zIndex;
  },
  
  setMaskZindex : function(zIndex) {
    this.maskZindex = this.getZindex(zIndex);
    $(this.maskId).style.zIndex = this.maskZindex;
  },

  getZindex: function(zIndex) {
    return ZindexManager.getIndex(zIndex);
  },
  
  open: function(zIndex) {
    if (this.options.modal && !$(this.maskId)) {
      this.buildMask(zIndex);
      zIndex = this.maskZindex + 1;
    }
    this.setWindowZindex(zIndex);
    Element.show(this.element);
    this.setFrameSize();
  },
      
  close: function() {
    if (!this.options.preClose(this)) return;
    this.element.style.zIndex = -1;
    this.maxZindex = -1;
    Element.hide(this.element);
    if (this.options.modal) {
      Window.modalIdList.pop();
      Element.remove(this.maskId);
      if (Window.modalIdList.length == 0) {
        Event.stopObserving(document, "keypress", Window.eventHandler.handleEvent.bindAsEventListener(this));
        Event.stopObserving(document, "keydown", Window.eventHandler.handleEvent.bindAsEventListener(this));
        Event.stopObserving(document, "keyup", Window.eventHandler.handleEvent.bindAsEventListener(this));
        Event.stopObserving(document, "focus", Window.eventHandler.handleEvent.bindAsEventListener(this));

      }
    }
    this.options.endClose(this);
  },

  minimize: function(event) {
    if (this.minFlag) {
      if (!this.options.preRevertMinimize(this)) return;
      Element.toggle(this.windowBody);
      if (this.maxFlag) {
        this.minFlag = false;
        this.setMax();
      } else {         
        var newStyle = {height:this.currentSize[1]}
        this.setBodyHeight(newStyle);
        this.element.style.width = this.currentSize[0];
        this.element.style.height = this.currentSize[1]; 
        this.element.style.left = this.currentPos[0];
        this.element.style.top = this.currentPos[1];
        this.maxFlag = false;
        this.minFlag = false;
        this.options.endRevertMinimize(this);
      }
    } else {
      if (!this.options.preMinimize(this)) return;
      Element.toggle(this.windowBody);
      if (!this.maxFlag) {
        this.currentPos = [Element.getStyle(this.element, 'left'), Element.getStyle(this.element, 'top')];
        this.currentSize = [Element.getStyle(this.element, 'width'), Element.getStyle(this.element, 'height')];
      }
      this.setMin();
      this.minFlag = true;
      this.options.endMinimize(this);
    }
    this.setFrameSize();
  },
    
  maximize: function(event) {
    if (this.maxFlag) {
      if (this.minFlag) {
        Element.toggle(this.windowBody);
        this.minFlag = false;
        this.setMax();
      } else {
        if (!this.options.preRevertMaximize(this)) return;
        var newStyle = {height:parseInt(this.currentSize[1])}
        this.setBodyHeight(newStyle);
        this.element.style.width = this.currentSize[0];
        this.element.style.height = this.currentSize[1]; 
        this.element.style.left = this.currentPos[0];
        this.element.style.top = this.currentPos[1];
        this.maxFlag = false;
        this.minFlag = false;        
        document.body.style.overflow = '';
        this.element.style.position = this.position;
        this.element.style.zIndex = this.currentZindex;
        for(var i = 0; i < this.nodeArray.length; i++) {
          this.parent.appendChild(this.nodeArray[i]);
        }
        this.options.endRevertMaximize(this);
      }
    
    } else {
      if (!this.options.preMaximize(this)) return;
      if (!this.minFlag) {
        this.currentPos = [Element.getStyle(this.element, 'left'), Element.getStyle(this.element, 'top')];
        this.currentSize = [Element.getStyle(this.element, 'width'), Element.getStyle(this.element, 'height')];        
      } else {
        Element.toggle(this.windowBody);
        this.minFlag = false;
      }
      this.parent = this.element.parentNode;
      this.nodeArray = new Array();
      this.setNodePosition();
      this.nodeIndex = 0;
      this.position = Element.getStyle(this.element, 'position');
      document.body.style.overflow = 'hidden';
      document.body.appendChild(this.element);
      this.element.style.position = 'absolute';
      this.setMax();
      this.maxFlag = true;
      this.options.endMaximize(this);
    }
    this.setFrameSize();
  },
    
  setNodePosition : function() {
    var children = this.parent.childNodes;
    for (var i = 0; i < children.length; i++) {
      var child = children[i];
      if (child.id == this.elementId) {
        this.nodeIndex = i;
      }
      this.nodeArray.push(child);
    }
  },
    
  setMin : function() {
    var minHeight = this.header.offsetHeight + this.bottom.offsetHeight;
    var minWidth = this.options.minWidth;
    this.element.style.height = minHeight + 'px';
    this.element.style.width = minWidth + 'px';
  },
        
  setMax : function(zIndex) {
    var maxW = Element.getWindowWidth();
    var maxH = Element.getWindowHeight();
    var newStatus = {height:maxH}
    with(this.element.style) {
      width = maxW + 'px';
      height = maxH + 'px';
      left = '0px';
      top = '0px';
    }
    this.setBodyHeight(newStatus);
    this.setWindowZindex(zIndex);  
  },
  
  setFullSize: function(element) {
    var target = $(element);
    if (target && target.nodeType != 3) {
      var elements = target.childNodes;
      for (var i = 0; i < elements.length; i++) {

        if (elements[i] && elements[i].style) {
          var tmpOffset;

          tmpOffset = Position.cumulativeOffset(elements[i]);
        
          var elW = 0;
          var width = elements[i].style.width;
          if (width) {
            var index = -1;
            if ((index = width.indexOf('px', 0)) > 0) {
              elW = parseInt(width);
            } else if ((index = width.indexOf('%', 0)) > 0) {
              var pw = this._getParentWidth(elements[i].parentNode);;
              var par = parseInt(width);
              elW = pw * par / 100;  
            }       
          } else if (elements[i] == document.body) {
            elW = Element.getWindowWidth();
          }      
        
          var elH = 0;
          var height = elements[i].style.height;
          if (height) {
            var index = 0;
            if ((index = height.indexOf('px', 0)) > 0) {
              elH = parseInt(height);
            } else if ((index = height.indexOf('%', 0)) > 0) {
              var ph = this._getParentHeight(elements[i].parentNode);
              var par = parseInt(height);
              elH = ph * par / 100;
            }       
          } else if (elements[i] == document.body) {
            elH = Element.getWindowHeight();
          }  
          var tmpWidth = tmpOffset[0] + elW;
          var tmpHeight = tmpOffset[1] + elH;

          if(tmpWidth > this.maskSize[0]) {
            this.maskSize[0] = tmpWidth;  
          }
          if(tmpHeight > this.maskSize[1]) {
            this.maskSize[1] = tmpHeight;
          }        
          this.setFullSize(elements[i]);
        }
      }
    }
  },
  
  _getParentWidth: function(parent) {
    if (parent && parent.style) {
      var width = parent.style.width;
      var index = 0;
      if (width) {
        if ((index = width.indexOf('px', 0)) > 0) {
      return parseInt(width);
        } else if ((index = width.indexOf('%', 0)) > 0) {
          var pw = this._getParentWidth(parent.parentNode);
      
          var par = parseInt(width);
          return pw * par / 100;
        } else if (!width.isNaN) {
          return parseInt(width);
        }      
      } else if (parent == document.body){
        return Element.getWindowWidth();
      }
    }
  },
  
  _getParentHeight: function(parent) {
    if (parent && parent.style) {
      var height = parent.style.height;
      var index = 0;
      if (height) {
        if ((index = height.indexOf('px', 0)) > 0) {
      return parseInt(height);
        } else if ((index = height.indexOf('%', 0)) > 0) {
          var ph = this._getParentHeight(parent.parentNode);
      var par = parseInt(height);
          return ph * par / 100;
        } else if (!height.isNaN) {
          return parseInt(height);
        }      
      } else if (parent == document.body){
        return Element.getWindowHeight();
      }
    }
  },
  
  setBodyHeight: function(newStyle) {
    var height = parseInt(newStyle.height);
    if (height > this.options.minHeight) {
      var newHeight = (height - this.header.offsetHeight - this.bottom.offsetHeight) + 'px';
      this.windowBody.childNodes[0].style.height = newHeight;
      this.windowBody.childNodes[1].style.height = newHeight;
      this.windowBody.childNodes[2].style.height = newHeight;
      this.windowBody.style.height = newHeight;
    }

    this.setFrameSize();
  },

  center: function() {
    var w = parseInt(Element.getStyle(this.element, 'width'));
    var h = parseInt(Element.getStyle(this.element, 'height'));

    var pOffset = Position.cumulativeOffset(Position.offsetParent(this.element));

    var left = (Element.getWindowWidth() / 2) - (w / 2);
    var top = (Element.getWindowHeight() / 2) - (h / 2);
    var scrollTop = (document.documentElement.scrollTop || document.body.scrollTop);
    var scrollLeft = (document.documentElement.scrollLeft || document.body.scrollLeft);

    top += scrollTop - pOffset[1];
    left += scrollLeft - pOffset[0];
    top = (top > 0) ? top : 0;
    left = (left > 0) ? left : 0;
    Element.setStyle(this.element, {left: left + 'px', top: top + 'px'});
  },

  enableResizing: function() {
    var resTop = this.options.resizeY ? 6 : 0;
    var resBottom = this.options.resizeY ? 6 : 0;
    var resLeft = this.options.resizeX ? 6 : 0;
    var resRight = this.options.resizeX ? 6 : 0;
    this.resizeable = new ResizeableWindowEx(this.element, { 
                        top: resTop,
                        bottom: resBottom,
                        left: resLeft,
                        right: resRight,
                        minWidth:this.options.minWidth, 
                        minHeight:this.options.minHeight,
                        draw: this.setBodyHeight.bind(this),
                        resize: this.options.endResize
                      });
  },

  disableResizing: function() {
    this.resizeable.destroy();
  }
}


// Copyright (c) 2005 spinelz.org (http://script.spinelz.org/)
// 
// This code is substantially based on code from script.aculo.us which has the 
// following copyright and permission notice
//
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var DraggableWindowEx = Class.create();
Object.extend(DraggableWindowEx.prototype, Draggable.prototype);
Object.extend(DraggableWindowEx.prototype, {
  initDrag: function(event) {
    if(Event.isLeftClick(event)) {    
      // abort on form elements, fixes a Firefox issue
      var src = Event.element(event);
      if(src.tagName && (
        src.tagName=='INPUT' ||
        src.tagName=='SELECT' ||
        src.tagName=='OPTION' ||
        src.tagName=='BUTTON' ||
        src.tagName=='TEXTAREA')) return;
        
      if(this.element._revert) {
        this.element._revert.cancel();
        this.element._revert = null;
      }
      
      var pointer = [Event.pointerX(event), Event.pointerY(event)];
      var pos     = Position.cumulativeOffset(this.element);
      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });

      var zIndex = ZindexManager.getIndex();
      this.originalZ = zIndex;
      this.options.zindex = zIndex;
      Element.setStyle(this.element, {zIndex: zIndex});
      
      Draggables.activate(this);
      Event.stop(event);
    }
  },

  endDrag: function(event) {
    if(!this.dragging) return;
    this.stopScrolling();
    this.finishDrag(event, true);

    this.options.endDrag();
    Event.stop(event);
  }
});

