/*****************************************************************************
  Usage:
     var popup = new PopupWindow( "My Title" );
     #1 Change Content Area
	     appendChild(...), setInnerHTML(...), OR getContent()
     #2 setOptions(...)
     #3 popup.show()
  
  
  NOTES:
     For IE, an iframe is created each time to force all native windows components (e.g.  selects )
     to disappear.  All other browsers behave correctly.
     
  Author: Steven Lee

  To Do:
  $(this.options.setfocus).focus();

*****************************************************************************/

Voy.PopupWindow = Class.create();
Voy.PopupWindow.prototype = {
  initialize: function(title, html, options) {
    this.options = {
      onclosed: Prototype.emptyFunction,
      prefix: "pop",
      left: 50,
      top: 150,
      width: this.getDefaultWidth(html),
      height: this.getDefaultHeight(html),
      onescape: this.hide.bind(this),
      onenter: Prototype.emptyFunction,
      overflow: "auto",
      closeimg: "/common/assets/images/buttons/close_up.gif",
      modal: true,
      centered: false,
      showtitlebar: Voy.isDefined( Voy.Env ) ? Voy.Env.Browser.isSafari() : false,
      setfocus: false,
      fixedPosition: Voy.isDefined( Voy.Env ) ? Voy.Env.Browser.isSafari() : false
    };
    
    Object.extend( this.options, options );
    this.destroyables = [];
    this.divs = {};
    this.divs.text = Voy.span( { className: this.getClassName( "title-text" ) }, title );
    
    var divsBar = $A();
    divsBar.push( this.divs.text );
    
    if( Voy.isNotBlank( this.options.closeimg ) ) {
      this.divs.close = Voy.img( { className: this.getClassName( "title-close-img" ), src: this.options.closeimg }   );
      this.destroyables.push( new Voy.ImageObserver( this.divs.close, { enabled: "up", down: "down", disabled: "disabled" }, { onclick: this.hide.bind(this) } ) );
      divsBar.push( Voy.span( { className: this.getClassName( "title-close" ) }, [ this.divs.close ] ) );
    }

    this.hiddenSelects = $A();
    this.divs.title = Voy.div( { className: this.getClassName( "title" ) }, divsBar );
    this.divs.content = Voy.div( { className: this.getClassName( "content" ) } );
    this.divs.content.style.overflow = this.options.overflow;

    this.window = Voy.div( { className: this.getClassName( "window" ) }, [ this.options.showtitlebar ? this.divs.title : '',, this.divs.content ]);
    Element.hide( this.window );
    document.body.appendChild( this.window );
    
   if( Voy.isNotBlank( html ) ) {
      if( Voy.isString( html ) ) {
        var div = $( html );
        if( Voy.isBlank( div ) ) {
          this.divs.content.innerHTML = html;
        } else {
          Element.remove( div );
          this.divs.content.appendChild( div );
          Element.show( div );
          Element.show( this.divs.content );
        }
      } else {
        if( html.parentNode )
          Element.remove( html );
        this.divs.content.appendChild( html );
        Element.show( html );
        Element.show( this.divs.content );
      }
    }
    
    Element.setSelectable(this.divs.title, false);
    this.setBounds( this.options );
    
    if ( ! this.options.fixedPosition ) {
      this.draggable = new Draggable( this.window, 
      { 
        handle: this.divs.title, 
        change: this.resetBackground.bind(this),
        starteffect: Prototype.emptyFunction,
        endeffect: Prototype.emptyFunction
      } );
      this.destroyables.push(this.draggable);
    }
    this.keypressevent = this.onkeypress.bindAsEventListener(this);
  },
  changeOptions: function(options) {
    Object.extend( this.options, options );
  },
  onkeypress: function(evt) {
    switch( evt.keyCode ) {
      case Event.KEY_ESC:
        this.options.onescape ? this.options.onescape(evt) : "";
        break;
      case Event.KEY_RETURN:
        this.options.onenter(evt);
        break;
    }
  },
  getDefaultWidth: function(html) {
    html = ( html || this.window );
    var width;
    try {
      width = Element.getWidth(html);
    } catch(e) {}
    return width ? width : 480;
  },
  getDefaultHeight: function(html) {
    html = ( html || this.window );
    var height;
    try {
      height = Element.getHeight(html);
    } catch(e) {}
    return height ? height : 200;
  },
  setBounds: function(bounds) {
    var resize = ( bounds.width || bounds.height );
    
    bounds = Object.extend( Object.extend( {}, this.options ), bounds );
    
    if( bounds.center ) {
      bounds.left = bounds.center.x - ( bounds.width / 2 )
      bounds.top = bounds.center.y - ( bounds.height / 2 )
    }
    
    if( Voy.isIE() ) {
      Element.setBounds( this.window, { left: bounds.left, top: bounds.top, height: bounds.height, width: bounds.width } );
      Element.setBounds( this.divs.content, { height: bounds.height, width: bounds.width - 2 } );
      Element.setWidth( this.divs.title, bounds.width );
    } else {
     Element.setBounds( this.window, { left: bounds.left, top: bounds.top, width: bounds.width } );
     Element.setBounds( this.divs.content, { height: bounds.height - Element.getHeight( this.divs.title ) - 4 } );
   }
  },
  getClassName: function(className) {
    if (this.options.showtitlebar) {
      return this.options.prefix + "-" + className;
    } else {
      return this.options.prefix + "-notitlebar-" + className;
    }
  },
  getContent: function() {
    return this.divs.content;
  },
  setInnerHTML: function( html ) {
    this.getContent().innerHTML = html;
  },
  appendChild: function( child ) {
    return this.content.appendChild( child );
  },
  hide: function() {
    Element.hide( this.window );
    Event.stopObserving( this.window, "keypress", this.keypressevent );
    if( this.options.modal ) {
      Element.hide( this.divs.background );
      if( Voy.isNotBlank( this.divs.iFrame ) ) {
        Element.remove( this.divs.iFrame );
        this.divs.iFrame = null;
      }
          
      Event.stopObserving( window, 'resize', this.divs.background.onResizeFxn );
    }
    this.options.onclosed(this);
  },
  show: function(options) {
    Event.observe( this.window, "keypress", this.keypressevent );

    if ( this.options.centered ) {
      try {
        Effect.Center( this.window );
      } catch ( e ) { alert( 'you must include effect_ext.js: ' + e ); }
    }

    if ( this.options.modal ) {
      if ( Voy.isNotBlank( options ) )
        this.setBounds( options );
  
      if ( Voy.isBlank( this.divs.iFrame ) && Voy.isIE() ) {
        this.divs.iFrame = Voy.iframe( { className: this.getClassName( "background-iframe" ), src: Voy.getPath("blank.html") } );
        document.body.appendChild( this.divs.iFrame );
        Position.absolutize( this.divs.iFrame );
        this.fitToPage(this.divs.iFrame);
        Element.setOpacity( this.divs.iFrame, 0 );
      }
      
  	  if ( Voy.isBlank( this.divs.background ) ) {
	      this.divs.background = Voy.div( { className: this.getClassName( "background" ) } );
	      document.body.appendChild( this.divs.background );
	      Position.absolutize( this.divs.background );
	      this.fitToPage(this.divs.background);
  	  }
  	  
      this.divs.background.onResizeFxn = this.onresize.bindAsEventListener(this);
      Event.observe( window, "resize", this.divs.background.onResizeFxn );
      this.resetBackground();
      Element.hide( this.divs.background );
      Effect.Appear(this.divs.background, { duration: 2.0, to: 0.4, from: 0 });
      window.scrollTo(0,0);
    }
    Effect.Appear(this.window, { duration: 0.5, afterFinish: function(myWindow) { 
        var elems = $A($(myWindow).getElementsByTagName('*')).inject([],
                      function(elements, child) {
                        if (Form.Element.Serializers[child.tagName.toLowerCase()]) {
                          elements.push(Element.extend(child));
                        }
                        return elements;
                      });
        var elem = elems.find( function(element) {
                                 return element.type != 'hidden' && !element.disabled && ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
                               });
        if ( Voy.isNotBlank( elem ) ) {
          Field.activate( elem );
        }
      }.bind( this, this.window ) } );
  },
  visibile: function() {
    return Element.visible( this.window );
  },
  fitToPage: function(div) {
    var page = Element.getPageDimension();
    Element.setHeight( div, page.height );
    Element.setWidth( div, page.width );
  },
  resetBackground: function() {
    this.fitToPage( this.divs.background );
  },
  onresize: function() {
    this.resetBackground();
  },  
  destroy: function() {
    this.hide();
    for( var i = 0; i < this.destroyables.length; i++ ) {
      this.destroyables[i].destroy();
    }
  }
}


