/*
 *  popover dialogs © 2008-2009, Horus Web Engineering Ltd
 *
 *  $Id: popover.js,v 1.21 2009-10-21 14:01:44 horus Exp $
 *
 *  licensed under the terms of the GNU Lesser General Public License:
 *    http://www.opensource.org/licenses/lgpl-license.php
 *
 *  needs horus.js, dom.js
 *  uses xmlhttp.js, status.js if go/nogo are used
 *
 */

horus.script.load('dom');


horus.popover=
  function ( popover, options ) {
    popover=horus.getElement(popover);
    horus.popover.options(popover, options);

    if (popover._moveable) {
      horus.insertChild(popover);

      if (!popover.onmousedown)
	popover.onmousedown=
	  function ( event ) {
	    if (!this._moveable) return;
	    event=new horus.event(event);
	    this.top=this.offsetTop;
	    this.left=this.offsetLeft;
	    this._ey=event.y;
	    this._ex=event.x;
	    if (horus.popover.moving) horus.popover.endmove();
	    horus.popover.moving=this;
	    horus.eventListener(document.body, 'mousemove', horus.popover.move);
	    horus.eventListener(document.body, 'mouseup', horus.popover.endmove);
	    horus.eventListener(document.body, 'selectstart', horus.popover.skip);
	    horus.eventListener(document.body, 'dragstart', horus.popover.skip);
	    popover.style.cursor='move';
          };

    }

    if (popover._height) popover.style.height=horus.sizevalue(popover._height);

    if (popover._width)
      popover.style.width=horus.sizevalue(popover._width);
    else if (horus.brokenDOM)
      popover.style.width=(horus.windowsize().width>>1)+'px';

    var windowsize=horus.windowpos();
    var maxtop=windowsize.bottom-popover.offsetHeight-4;
    var maxleft=windowsize.right-popover.offsetWidth-4;

    var position=popover._reference ?
      horus.getposition(popover._reference) :
      { top: horus.scrollv(), left: horus.scrollh() };

    position.top+=popover._y;
    position.left+=popover._x;
    if (position.top>maxtop) position.top=maxtop;
    if (position.left>maxleft) position.left=maxleft;
    popover.style.top=position.top+'px';
    popover.style.left=position.left+'px';
    popover.style.visibility='visible';
    popover.onkeyup=horus.popover.key;
    popover._form=horus.firstTag(popover, 'form');

    if (horus.brokenDOM && popover._form) {
      if (horus.ieold) popover._form.style.width=popover._form.offsetWidth;
      popover._form.style.height='100%';
    }

    if (popover._focus) {
      if (typeof popover._focus=='boolean')
	popover._focus=horus.searchTag(popover, false, horus.getTags.input, '.closebox');
      else if (typeof popover._focus=='string')
	popover._focus=document.getElementById(popover._focus);

      if (popover._focus) popover._focus.focus();
    }

    return popover;
  };


horus.popover.options=
  function ( popover, options ) {
    popover=horus.getElement(popover);

    for (var key in horus.popover.options.defaults)
      popover['_'+key]=horus.popover.options.defaults[key];

    if (options!=null)
      switch (typeof options) {

      case 'string':  popover._reference=options; break;
      case 'number':  popover._y=options;         break;
      case 'boolean': popover._moveable=options;  break;

      case 'object':
        if (horus.isElement(options))
	  popover._reference=options;
	else
	  for (key in options)
	    if (key in horus.popover.options.defaults) popover['_'+key]=options[key];


      }

    if (popover._reference) popover._reference=horus.getElement(popover._reference);
  };


horus.popover.options.defaults=
  { reference:   null,
    y:           20,
    x:           80,
    height:      null,
    width:       null,
    moveable:    false,
    focus:       true,
    escape:      true,
    method:      null,
    action:      null,
    callback:    null,
    params:      false,
    formparams:  false,
    ajaxoptions: null };


horus.popover.key=
  function ( event ) {
    event=new horus.event(event);
    var target=event.target;

    switch (event.keyCode) {

    case 27:
      var onescape=horus.popover.get(target)._escape;

      if (onescape)
	switch (typeof onescape) {

	case 'boolean':  horus.popover.nogo(event); break;
	case 'function': onescape(event); break;
	case 'string':   document.getElementById(onescape).onclick(event); break;
	case 'object':   onescape.onclick(event); break;

	}

      break;

    case 37:
      if (horus.checkTag(target, 'input:type=button=submit,button')) {
	target=horus.previousTag(event.target, horus.getTags.input);
	if (target) target.focus();
      }

      break;

    case 39:
      if (horus.checkTag(target, 'input:type=button=submit,button')) {
	target=horus.nextTag(event.target, horus.getTags.input);
	if (target) target.focus();
      }

      break;

    }

    return true;
  };


horus.popover.move=
  function ( event ) {
    var popover=horus.popover.moving;
    if (!popover) return;
    event=new horus.event(event);
    var dy=event.y-popover._ey;
    var dx=event.x-popover._ex;
    if (dy*dy<9 && dx*dx<9) return;
    popover.style.top=(popover.top+=dy)+'px';
    popover.style.left=(popover.left+=dx)+'px';
    popover._ey=event.y;
    popover._ex=event.x;
    return false;
  };


horus.popover.endmove=
  function () {
    var popover=horus.popover.moving;
    if (!popover) return;
    popover.style.cursor=null;
    horus.removeListener(document.body, 'dragstart', horus.popover.skip);
    horus.removeListener(document.body, 'selectstart', horus.popover.skip);
    horus.removeListener(document.body, 'mouseup', horus.popover.endmove);
    horus.removeListener(document.body, 'mousemove', horus.popover.move);
    horus.popover.moving=false;
  };


horus.popover.skip=function () { return false };


horus.popover.hide=
  function ( popover ) {
    popover=horus.getElement(popover);

    if (!horus.hasClass(popover, 'popover'))
      popover=horus.parentTag(popover, 'div.popover');

    horus.visibility(popover, false);
    return popover._params;
  };


horus.popover.get=
  function ( popover ) {
    if (!horus.isElement(popover)) {
      if (!(popover instanceof horus.event)) popover=new horus.event(popover);
      popover=popover.target;
    }

    if (!horus.hasClass(popover, 'popover'))
      popover=horus.parentTag(popover, 'div.popover');

    return popover;
  };


horus.popover.go=
  function ( popover, params, method, action, callback, ajaxoptions ) {
    var direct=!horus.isElement(popover);
    popover=horus.popover.get(popover);
    var async;

    if (direct || !params)
      params=popover._params;
    else if (popover._params)
      for (var tag in popover._params)
	if (!(tag in params)) params[tag]=popover._params[tag];

    if (popover._form && popover._formparams) {
      if (!params) params={};

      for (var i=0; i<popover._form.elements.length; i++) {
	var field=popover._form.elements[i];
	if (field.name) params[field.name]=horus.getvar(field);
      }
    }

    if (direct || method==null) method=popover._method;
    if (direct || action==null) action=popover._action;
    if (direct || callback==null) callback=popover._callback;

    if (callback)
      if (callback instanceof Array)
	callback.push(params, popover);
      else
	callback=[ callback, params, popover ];

    var response;

    if (typeof method=='function' || action && typeof action=='object') {
      if (!action) action=window;
      if (typeof method!='function') method=action[method];
      response=method.call(action, params);
    } else {
      if (direct || ajaxoptions==null) ajaxoptions=popover._ajaxoptions;

      if (callback) {
	async=true;
	horus.ajax(action, method, params, callback, ajaxoptions);
      } else
	response=horus.ajax(action, method, params, null, ajaxoptions);

    }

    if (!async)
      if (callback)
	horus.call(callback, response, null);
      else if (response)
	horus.popover.hide(popover);

    return false;
  };


horus.popover.nogo=
  function ( popover ) {
    popover=horus.popover.get(popover);
    var callback=popover._callback;

    if (callback) 
      horus.call(callback, false, [ popover._params, popover ]);
    else {
      horus.popover.hide(popover);
      horus.status.clear();
    }
  };


horus.script.loaded('popover');
