/*
 * Ext JS Library 2.1
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * http://extjs.com/license
 */

window.size = function()
{
	var w = 0;
	var h = 0;

	//IE
	if(!window.innerWidth)
	{
		//strict mode
		if(!(document.documentElement.clientWidth == 0))
		{
			w = document.documentElement.clientWidth;
			h = document.documentElement.clientHeight;
		}
		//quirks mode
		else
		{
			w = document.body.clientWidth;
			h = document.body.clientHeight;
		}
	}
	//w3c
	else
	{
		w = window.innerWidth;
		h = window.innerHeight;
	}
	return {width:w,height:h};
}

window.center = function()
{
	var hWnd = (arguments[0] != null) ? arguments[0] : {width:0,height:0};

	var _x = 0;
	var _y = 0;
	var offsetX = 0;
	var offsetY = 0;

	//IE
	if(!window.pageYOffset)
	{
		//strict mode
		if(!(document.documentElement.scrollTop == 0))
		{
			offsetY = document.documentElement.scrollTop;
			offsetX = document.documentElement.scrollLeft;
		}
		//quirks mode
		else
		{
			offsetY = document.body.scrollTop;
			offsetX = document.body.scrollLeft;
		}
	}
	//w3c
	else
	{
		offsetX = window.pageXOffset;
		offsetY = window.pageYOffset;
	}

	_x = ((this.size().width-hWnd.width)/2)+offsetX;
	_y = ((this.size().height-hWnd.height)/2)+offsetY;

	return{x:_x,y:_y};
}


Ext.ux.Portal = Ext.extend(Ext.Panel, {
  layout: 'column',
  region: 'center',
  cls:'x-portal',
  border: false,
  defaultType: 'portalcolumn',

  initComponent : function(){
    Ext.ux.Portal.superclass.initComponent.call(this);
    this.addEvents({
      validatedrop:true,
      beforedragover:true,
      dragover:true,
      beforedrop:true,
      drop:true
    });
  },

  initEvents : function(){
    Ext.ux.Portal.superclass.initEvents.call(this);
    this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
  },

  getAllWidgets: function(){
    var res = [];
    if(this.items != undefined){
      for(var i=0; i<this.items.getCount(); i++){
        var col = this.items.itemAt(i);
        if(col.items != undefined){
          for(var j=0; j<col.items.getCount(); j++){
            var widget = col.items.itemAt(j);
            res.push(widget);
          }
        }
      }
    }
    return res;
  },

  getCheckboxes: function() {
    var res = [];
    var allWidgets = this.getAllWidgets();
    for(var i=0; i<allWidgets.length; i++){
      res.push({
        xtype: 'checkbox',
        boxLabel: allWidgets[i].title,
        id: 'c-'+allWidgets[i].dbId,
        checked: !allWidgets[i].hidden,
        widget: allWidgets[i]
      });
    }
    return res;
  }
});
Ext.reg('portal', Ext.ux.Portal);


Ext.ux.Portal.DropZone = function(portal, cfg){
  this.portal = portal;
  Ext.dd.ScrollManager.register(portal.body);
  Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg);
  portal.body.ddScrollConfig = this.ddScrollConfig;
};

Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {
  ddScrollConfig : {
    vthresh: 50,
    hthresh: -1,
    animate: true,
    increment: 200
  },

  createEvent : function(dd, e, data, col, c, pos){
    return {
      portal: this.portal,
      panel: data.panel,
      columnIndex: col,
      column: c,
      position: pos,
      data: data,
      source: dd,
      rawEvent: e,
      status: this.dropAllowed
    };
  },

  notifyOver : function(dd, e, data){
    var xy = e.getXY(), portal = this.portal, px = dd.proxy;

    var ws = window.size();

    if(!(/Safari/).test(navigator.userAgent)){
      if((xy[1] - document.documentElement.scrollTop) > (ws.height - 70)){
        document.documentElement.scrollTop += 20;
      }

      if((xy[1] - document.documentElement.scrollTop) < 50){
        document.documentElement.scrollTop -= 20;
      }
    } else {
      if((xy[1] - document.body.scrollTop) > (ws.height - 70)){
        document.body.scrollTop += 20;
      }

      if((xy[1] - document.body.scrollTop) < 50){
        document.body.scrollTop -= 20;
      }
    }

    // case column widths
    if(!this.grid){
      this.grid = this.getGrid();
    }

    // handle case scroll where scrollbars appear during drag
    var cw = portal.body.dom.clientWidth;
    if(!this.lastCW){
      this.lastCW = cw;
    }else if(this.lastCW != cw){
      this.lastCW = cw;
      portal.doLayout();
      this.grid = this.getGrid();
    }

    // determine column
    var col = 0, xs = this.grid.columnX, cmatch = false;
    for(var len = xs.length; col < len; col++){
      if(xy[0] < (xs[col].x + xs[col].w)){
        cmatch = true;
        break;
      }
    }
    // no match, fix last index
    if(!cmatch){
      col--;
    }

    // find insert position
    var p, match = false, pos = 0,
    c = portal.items.itemAt(col),
    items = c.items.items;

    for(var len = items.length; pos < len; pos++){
      p = items[pos];
      var h = p.el.getHeight();
      if(h !== 0 && (p.el.getY()+(h/2)) > xy[1]){
        match = true;
        break;
      }
    }

    var overEvent = this.createEvent(dd, e, data, col, c,
      match && p ? pos : c.items.getCount());

    if(portal.fireEvent('validatedrop', overEvent) !== false &&
      portal.fireEvent('beforedragover', overEvent) !== false){

      // make sure proxy width is fluid
      px.getProxy().setWidth('auto');

      if(p){
        px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
      }else{
        px.moveProxy(c.el.dom, null);
      }

      this.lastPos = {
        c: c,
        col: col,
        p: match && p ? pos : false
      };
      this.scrollPos = portal.body.getScroll();

      portal.fireEvent('dragover', overEvent);

      return overEvent.status;;
    }else{
      return overEvent.status;
    }

  },

  notifyOut : function(){
    delete this.grid;
  },

  notifyDrop : function(dd, e, data){
    delete this.grid;
    if(!this.lastPos){
      return;
    }
    var c = this.lastPos.c, col = this.lastPos.col, pos = this.lastPos.p;

    var dropEvent = this.createEvent(dd, e, data, col, c,
      pos !== false ? pos : c.items.getCount());

    if(this.portal.fireEvent('validatedrop', dropEvent) !== false &&
      this.portal.fireEvent('beforedrop', dropEvent) !== false){

      dd.proxy.getProxy().remove();
      dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
      if(pos !== false){
        c.insert(pos, dd.panel);
      }else{
        c.add(dd.panel);
      }

      c.doLayout();

      this.portal.fireEvent('drop', dropEvent);

      // scroll position is lost on drop, fix it
      var st = this.scrollPos.top;
      if(st){
        var d = this.portal.body.dom;
        setTimeout(function(){
          d.scrollTop = st;
        }, 10);
      }

    }
    delete this.lastPos;
  },

  // internal cache of body and column coords
  getGrid : function(){
    var box = this.portal.bwrap.getBox();
    box.columnX = [];
    this.portal.items.each(function(c){
      box.columnX.push({
        x: c.el.getX(),
        w: c.el.getWidth()
      });
    });
    return box;
  }
});
