/*
 *  popover dialogs © 2008-2010, Horus Web Engineering Ltd
 *
 *  $Id: popover.js,v 1.25 2010-04-21 10:40:25 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);

	if (popover._focus && horus.hasClass(popover._focus, 'closebox')) {
	  var node=horus.searchTag(popover, false, horus.getTags.input, '.closebox');
	  if (node) popover._focus=node;
	}
      } else if (typeof popover._focus=='string')
	popover._focus=document.getElementById(popover._focus);

      if (popover._focus) horus.focus(popover._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.create=
  function ( id, createoptions, displayoptions ) {
    var node=horus.getElement(id, true);

    if (!node) {
      if (!createoptions) createoptions={};
      var formname=createoptions.formname || 'popoverform'+document.forms.length;
      var title=createoptions.title || 'Please Confirm';
      var content=createoptions.content || '';
      var yesclass=createoptions.yesclass || 'del';
      var yeslabel=createoptions.yeslabel || 'yes';
      var noclass=createoptions.noclass || 'reset';
      var nolabel=createoptions.nolabel || 'no';
      var contentclass=createoptions.contentclass;

      if (contentclass && horus.isString(contentclass) && !/^\./.test(contentclass))
	contentclass={ classname: contentclass };

      node=horus.insertChild(document.body, [ 'div', '.popover' ]);
      node.$form=horus.appendChild(node, [ 'form', { name: formname } ]);
      node.$title=horus.appendChild(node.$form, [ 'h2', null, title ]);
      node.$content=horus.appendChild(node.$form, [ 'div', contentclass ]);
      if (content) horus.appendChild(node.$content, content);

      horus.appendChild
	(node.$form,
         [ 'div', '.endbutton',
	   [ 'input',
	     { type: 'button', classname: yesclass+' small button', value: yeslabel,
	       onclick: horus.popover.go } ], ' ',
	   [ 'input',
	     { type: 'button', classname: noclass+' small button', value: nolabel,
	       onclick: horus.popover.nogo } ] ]);

    }

    if (displayoptions!=null) node=horus.popover(node, displayoptions);
    return node;
  };


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) horus.focus(target);
      }

      break;

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

      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);
    if (popover._reference) horus.focus(popover._reference);
    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 || response==null)
	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');
