felixPopUp_v2 = {
  newPopUp : function ( params )
  {
    var popUpWorkObject = 
    {
      'pos_mode'       : 'right',
      'slide_mode'     : 'horizontal',
      'duration'       : 500,
      'duration_close' : 500,
      'scope_class'    : 'popup_scope',
      'width'          : '',
      'height'         : '',
      'fps'            : 24,
      
      'attachments' : {},
		  
		  'state'               : 'hidden',
		  'animatingAttachment' : null,
		  'toState'             : null,
		  'nextToSlideIn'       : null,
		  'onAfterSlideOut'     : "",
		  'onAfterSlideIn'      : "",
		  
		  
		  'constructor' : function ( params )
		  {
		     for( var key in params ) {
		       this[key] = params[key];
		     }
		     
		  },
      
      'setAttachChildTryAgain' : function ( p, c, params )
      {
        var today = new Date();
        var uniq_id = today.getUTCMilliseconds();
        uniq_id += today.getUTCSeconds() * 1000;
        
        uniq_id = "uniq_id" + uniq_id + "_" + Math.round( Math.random() * 1000 );
        eval( 'document.' + uniq_id + " = this;" );
        eval( 'document.' + uniq_id + "_params = {'p' : p, 'c' : c, 'params' : params };" );
        
        window.setTimeout( 'document.' + uniq_id + ".attachChildTryAgain('" + uniq_id + "', document." + uniq_id + "_params )", 300 );
      },
		  
		  'attachChildTryAgain' : function ( uniq_id, params_dump )
      {
        eval( 'delete document.' + uniq_id + ";" );
        this.attachChild( params_dump.p, params_dump.c, params_dump.params );
      },
		  
		  'attachChild' : function ( p, c, params )
		  { 
		    var c_id = c;
        var c = document.getElementById( c );
        
        var p_elem = document.getElementById( p );
        
        if( c == null || p_elem == null ){
          this.setAttachChildTryAgain( p, c_id, params );
          return;
        }
        
        var storedAttachment = this.getAttachmentByMenuId( c.id );
         
        if( storedAttachment != false ) {
          this.attachments[ p ] = storedAttachment;
        } else {
          this.attachments[ p ] = this.prepareChild( c, p, params );
          this.hideMenu( p );
          this.hideScope( p );
        }
        
        this.attachments[ p ].menu[ p+'_'+this.attachments[ p ].menu.id ] = this;
        
		  },

      'getAttachmentByMenuId': function ( id ) {
        for( var key in this.attachments ) {
          if( this.attachments[key].menu.id == id ){
            return this.attachments[key];
          }
        }
        return false;
      },

      'prepareChild' : function ( scope, p, params )
      {
        var menu = scope.cloneNode( true );

        while( scope.childNodes.length ) scope.removeChild( scope.childNodes[ scope.childNodes.length-1 ] );

        scope.appendChild( menu ); 
        scope.style.position = "absolute";
        scope.style.overflow = "hidden";
        scope.className = this.scope_class;
        scope.id = "";
        if( this.width ) {
          menu.style.width = this.width + 'px'; 
        }
        if( this.height ) {
          menu.style.height = this.height + 'px'; 
        }

        var attachment = { 'menu' : menu, 'scope' : scope };
        if( typeof params != "undefined" ) {
	        for( var key in params ) {
	          attachment[key] = params[key];
	        }
        }

        return attachment;
      },

      'slideIn' : function ( p, onAfterSlideIn )
      {
        if ( ! this.canAnimate( 'slideIn' ) ) return;
        
        this.state="moving";
        this.toState="showed";
        
        if( typeof p == 'string' ) { 
          var p = document.getElementById( p );
        }
        
        
        
        this.animatingAttachment = p.id;
        
        this.positioningBox( p, this.attachments[ p.id ].scope );

        this.unhideScope( p.id );
        this.hideMenu( p.id );
        
        if( typeof onAfterSlideIn != "undefined" ) {
          this.onAfterSlideIn = onAfterSlideIn;
        }
        
        this.animate( p.id );
      },
      
      'slideOut' : function ( p, onAfterSlideOut )
      {
        if ( ! this.canAnimate( 'slideOut' ) ) return;
        
        this.state="moving";
        this.toState="hidden";
        
        if( typeof p == 'string' ) { 
          var p = document.getElementById( p );
        }
        
        this.animatingAttachment = p.id;
        
        if( typeof onAfterSlideOut != "undefined" ) {
          this.onAfterSlideOut = onAfterSlideOut;
        }
        
        FelixLib_v1.unsetEvent(  document.body, 'click',  this.tmpEventfunc );
        this.animate( p.id );
      },
      
		  'toggle' : function ( p )
      {
        if ( ! this.canAnimate( 'toggle' ) ) return;
        
        if( this.state == "hidden" ) {
          this.slideIn( p );
          return;
        } 
        
        if( typeof p == 'string' ) { 
          var p = document.getElementById( p );
        }
        
        if( this.animatingAttachment != p.id ) {
          this.nextToSlideIn = p.id;
          this.slideOut( this.animatingAttachment );
          return;
        } else {
          this.slideOut( p );
        }
      },
		  
		  'canAnimate' : function ( action )
		  {
		    if( this.state == "moving" ) return false;
		    
		    switch( action ) {
          case 'slideIn' :
            if( this.state == "showed" ) return false;
            break;
          case 'slideIn' :
            if( this.state == "hidden" ) return false;
            break;
		    }
		    return true;
		  },
		  
		  'hideMenu' : function ( p )
		  {
		    var m = this.attachments[ p ].menu;
	    
		    switch( this.slide_mode ) {
		      case 'horizontal' :
		        m.style.marginLeft = -m.offsetWidth + 'px';
		        break;
		      case 'vertical' :
            m.style.marginTop = -m.offsetHeight + 'px';
            break;
		    }
		  },
		  
		  'hideScope' : function ( p )
		  {
		    var s = this.attachments[ p ].scope.style.display = "none";
		  },
		  'unhideScope' : function ( p )
      {
        var s = this.attachments[ p ].scope.style.display = "block";
      },
		  
		  'clickOut' : function ( event, p )
		  {
		    var target = event.target ? event.target : event.srcElement ? event.srcElement : '';

		    var in_menu = false;
		    
		    for ( var op = target; op; op = op.offsetParent ){
          if ( op == this.attachments[ p ].scope ){
            in_menu = true;
          }
        }
        
        if( !in_menu ) {
          this.slideOut( p );
          
          FelixLib_v1.unsetEvent(  document.body, 'click',  this.tmpEventfunc );
          this.tmpEventfunc = null;
        }
		  },
		  
		  'afterSlideOut' : function ( p ) 
		  {
		    this.state = "hidden";
        this.hideScope( p );
        
        if( this.onAfterSlideOut ) {
          eval( this.onAfterSlideOut );
          this.onAfterSlideOut = "";
        } else if( typeof this.attachments[ p ].onAfterSlideOut != "undefined" ) {
          eval( this.attachments[ p ].onAfterSlideOut );
        }
		  },
		  
		  'afterSlideIn' : function ( p ) 
      {
        this.state = "showed";
        
        var menu_id = this.attachments[ this.animatingAttachment ].menu.id;
        
        eval( "this.tmpEventfunc = function( event ){"+ 
                                  "  document.getElementById('"+menu_id+"')."+p+"_"+menu_id+".clickOut( event, '"+p+"' );"+
                                  "};"
            );
        
        FelixLib_v1.setEvent(  document.body, 'click',  this.tmpEventfunc );
        
        if( this.onAfterSlideIn ) {
          eval( this.onAfterSlideIn );
          this.onAfterSlideIn = "";
        } else if( typeof this.attachments[ p ].onAfterSlideIn != "undefined" ) {
          eval( this.attachments[ p ].onAfterSlideIn );
        }
      },
		  
		  'animate' : function ( p )
		  {
		    var menu = this.attachments[ p ].menu;
		    var sProperty = ( this.slide_mode == 'horizontal' ? 'marginLeft' : 'marginTop' );
		    var offset    = ( this.slide_mode == 'horizontal' ? menu.offsetWidth : menu.offsetHeight );
		    
		    var anim_params = {}; 
		    
		    var menu_id = this.attachments[ this.animatingAttachment ].menu.id;
		    
		    if ( this.toState == 'hidden' ) {
		      var to_cnd = -offset;
		      var step      = offset / ( this.duration_close / (1000/this.fps) );
		      anim_params.onAfterAnimate = escape( "document.getElementById('"+menu_id+"')."+p+"_"+menu_id+".afterSlideOut('"+p+"')" );
		    } else {
		      var to_cnd = 0;
		      var step      = offset / ( this.duration / (1000/this.fps) );
		      anim_params.onAfterAnimate = escape( "document.getElementById('"+menu_id+"')."+p+"_"+menu_id+".afterSlideIn('"+p+"')" );
		    }
		    FelixLib_v1.styleAnimate( menu_id, sProperty, to_cnd, step, anim_params );
		  },
		  
		  'positioningBox' : function ( p, c )
		  {
		    var top  = ( this.pos_mode == "bottom" ) ? p.offsetHeight + 2 : 0;
		    var left = ( this.pos_mode == "right" )  ? p.offsetWidth  + 2 : 0;
		  
		    for ( ; p; p = p.offsetParent ){
		       top  += p.offsetTop;
		       left += p.offsetLeft;
		    }
		  
		    c.style.position = "absolute";
		    c.style.top      = top +'px';
		    c.style.left     = left+'px';
		  }
		}
		popUpWorkObject.constructor( params );
		return popUpWorkObject;
	}
}; 

