// *******  image magnification script       *******
// *******  © by nexbyte gmbh, switzerland   *******
// *******  create: ??.??.2003 - tbruederli  *******
// *******  modify: 14.04.2004 - tbruederli  *******
// *******  requires: global.js, layers.js   *******


var nexmagnify_objects = new Array();
var nexmagnify_vars = new Object();

function nexmagnify_object(arg)
  {
  /* arguments:
  image         // name or object
  rectangle     // array(top,width,height,left); if not defined, the whole image is taken     
  factor        // zoom factor
  large_src     // location for large image
  display       // array{width, height, top, left [, parent:layer_object(), vis:'active|hover'] }
  */

  this.position = arg.display && arg.display.position ? arg.display.position : 'absolute';
  this.factor = arg.factor;

  this.id = nexmagnify_objects.length;
  this.obj = 'nexmagnify_objects['+this.id+']';
  nexmagnify_objects[this.id] = this;

  this.refimage = nex_get_object(arg.image);
  if(!this.refimage) return;

  this.refpos = get_image_pos(arg.image);
  this.offset_top = arg.rectangle ? arg.rectangle[0] : 0;
  this.offset_left = arg.rectangle ? arg.rectangle[3] : 0;
  this.width = arg.rectangle ? arg.rectangle[1] : this.refimage.width;
  this.height = arg.rectangle ? arg.rectangle[2] : this.refimage.height;
  this.vismode = arg.display && arg.display.vis ? arg.display.vis : 'hover';
  this.active = false;

  // create layers for magnify display
  var parent_layer = arg.display.parent && arg.display.parent.elm ? arg.display.parent : null;
  var hierarchy = parent_layer ? (parent_layer.hier!='' ? parent_layer.hier+'.' : '')+parent_layer.name : '';
  this.nested = hierarchy ? true : false;
  this.stage = new layer_object('nexmagstage'+this.id, hierarchy, null, {x:arg.display.left,
                                                                         y:arg.display.top,
                                                                         width:arg.display.width,
                                                                         height:arg.display.height,
                                                                         parent:(parent_layer ? parent_layer.elm : null),
                                                                         vis:0});
  this.stage.clip(0, arg.display.width, arg.display.height, 0);
  this.stage.css.overflow = 'hidden';

  var w = Math.ceil(this.width*this.factor) + 2;
  var h = Math.ceil(this.height*this.factor) + 2;

  this.detail = new layer_object('nexmagfocus'+this.id, this.stage.name, null, {x:0, y:0, width:w, height:h, vis:2, parent:this.stage.elm});
  this.detail.write('<img src="'+arg.large_src+'" name="nexmagnifyimg'+this.id+'">');


  // mouse over event-handler
  this.mover = function(e)
    {
    if(!this.magnify.active) return true;

    if(document.onmousemove)
      nexmagnify_vars.event_save = document.onmousemove;

    nexmagnify_vars.active = this.magnify.id;
    document.onmousemove = nexmagnify_mouse_move;
    if(bw.layers) document.captureEvents(Event.MOUSEMOVE);

    // kick mouse event function to move the layer to the right position
    this.magnify.mouse(e);

    // show the stage layer
    if(this.magnify.vismode=='hover')
      this.magnify.stage.show(this.magnify.nested?2:1);

    if(this.magnify.onmouseover)
      this.magnify.onmouseover(e);

    return true;
    }

  // mouse out event-handler
  this.mout = function(e)
    {
    if(!this.magnify.active) return true;

    nexmagnify_vars.active = null;
    document.onmousemove = nexmagnify_vars.event_save ? nexmagnify_vars.event_save : null;

    if(this.magnify.vismode=='hover')
      this.magnify.stage.show(0);

    if(this.magnify.onmouseout)
      this.magnify.onmouseout(e);

    return true;
    }

  // mouse move event-handler
  this.mouse = function(e)
    {
    var p = get_mouse_pos(e);
    var x = p.x-this.refpos.x-(this.offset_left);
    var y = p.y-this.refpos.y-(this.offset_top);

    if(x<0) x = 0;
    if(y<0) y = 0;
    if(x>this.width) x = this.width;
    if(y>this.height) y = this.height;

    var left = Math.round(this.stage.clip_width/2-x*this.factor);
    var top = Math.round(this.stage.clip_height/2-y*this.factor);

    var image = this.detail.doc.images['nexmagnifyimg'+this.id];
    if(!image || !image.complete)
      image = {width:Math.round(this.width * this.factor), height:Math.round(this.height * this.factor)};

    if(left>0) left = 0;
    if(top>0) top = 0;
    if(left<this.stage.clip_width-image.width) left = this.stage.clip_width-image.width;
    if(top<this.stage.clip_height-image.height) top = this.stage.clip_height-image.height;

    this.detail.move(left, top);

    // try to clip the detail layer in order to prevent showing window scrollbars (doesn't work!!)
    // this.detail.clip(0, Math.abs(left)+this.stage.clip_width+20, Math.abs(top)+this.stage.clip_height+20, 0);

    // window.status = 'move to: '+left+','+top+' (w:'+image.width+', h:'+image.height+')';
    }

  // set object reference and event-handlers to the image object
  this.activate = function()
    {
    this.refimage.magnify = this;
    this.refimage.onmouseover = nexmagnify_objects[this.id].mover;
    this.refimage.onmouseout = nexmagnify_objects[this.id].mout;

    if(this.refimage.style)
      this.refimage.style.cursor = 'crosshair';

    if(this.vismode=='active')
      this.stage.show(this.nested?2:1);

    this.active = true;
    }

  // remove eventhandlers
  this.disable = function()
    {
    this.refimage.onmouseover = null;
    this.refimage.onmouseout = null;

    if(this.refimage.style)
      this.refimage.style.cursor = 'default';

    if(this.vismode=='active')
      this.stage.show(0);

    this.active = false;
    }
  }


// global event-handler for document.onmousemove
function nexmagnify_mouse_move(e)
  {
  if(nexmagnify_vars.active!=null)
    nexmagnify_objects[nexmagnify_vars.active].mouse(e);

  return true;
  }
