/*
  Copyright INRA/CNRS

 Emmanuel.Courcelle@toulouse.inra.fr
 Jerome.Gouzy@toulouse.inra.fr
 Thomas.Faraut@toulouse.inra.fr

 This software is a computer program whose purpose is to provide a
 web-based interface for analyzing the different levels of genome
 conservations.

 This software is governed by the CeCILL license under French law and
 abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL
 license as circulated by CEA, CNRS and INRIA at the following URL
 "http://www.cecill.info".

 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
 liability.

 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
 software by the user in light of its specific status of free software,
 that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
 requirements in conditions enabling the security of their systems and/or
 data to be ensured and,  more generally, to use and operate it in the
 same conditions as regards security.

 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL license and that you accept its terms

*/
/*

=pod

=head1 NAME
 LipmPopup.js - Objects useful for displaying popups

=head1 SYNOPSIS

 LipmPopupBaseClass         A base class for displaying popups
     LipmPopupDummyClass    quite dummy, may be useful for developers
     LipmPopupSimpleClass   The popup is simply connected to a <div>
     LipmPopupYUIClass      The popup is an YUI popup
     LipmPopupYUITabClass   The popup is a tab, managed by a YUI TabView object

 LipmNewWindowClass         An object to open a new window from a link

=head1 CLASSES AND METHODS

=cut
*/
/*
=pod

=head1 class LipmPopupBaseClass

 Title           : LipmPopupBaseClass
 Class           : This abstract class implements two methods:
                        - Display: prints a message in the container and shows the container
                        - Close  : hides the container
 Constructor arg : popup_div : the id of the div we'll use as a popup
 Globals         : none

=cut
*/

LipmPopupBaseClass = Class.create({
	initialize: function(div)
	{
		this._div = $(div);
		if (this._div==null) {throw('ERROR - LipmPopupBaseclass - could not find ' + div);};
		this.__a_observers = $A();
	},
/*
=pod

=head2 procedure RegisterLinkObserver

 Title           : RegisterLinkObserver
 Usage           : o_popup.RegisterLinkObserver(o_new_window)
 Function        : Register some LipmNewwindowClass objects, the method Observe of all those objects will be called by Display,
                   so that the links inside the popup will be able to open new windows
 Args            : o_new_window A NewWindowClass object
 Globals         : none

=cut
*/
    RegisterLinkObserver: function(o_new_window)
	{
		this.__a_observers.push(o_new_window);
	},
/*
=pod

=head2 procedure _ObserveLinks

 Title           : _ObserveLinks
 Usage           : FROM A DERIVED CLASS, at the end of the function Display
 Function        : Call o.Observe for every registered observer
 Args            : o_new_window A NewWindowClass object
 Globals         : none
 Access          : protected

=cut
*/

	_ObserveLinks: function()
	{
		var top_id = this._div;
		this.__a_observers.each(function(o){o.Observe(top_id);});
	},

/*
=pod

=head2 procedure Partialdisplay

 Title           : PartialDisplay
 Usage           : o_popup.PartialDisplay(n,body);
 Function        : Look for the nth descendant of this._div belonging to the class PartialDisplay, and update this element with the body parameter
                   If such an element does not exist, the call is silently ignored
 Args            : n     the "number" to update
                   body  the html to insert inside this element
 Globals         : none

=cut
*/
	PartialDisplay: function (n,body)
	{
		var e_elt = this._div.select(' .PartialDisplay')[n];
		//if (e_elt != null) {e_elt.update(body);};
		if (e_elt != null) {e_elt.innerHTML = body;};
	},
/*
=pod

=head2 procedure Display

 Title           : Display
 Usage           : o_popup.Display(body,header,footer,x,y);
 Function        : Print a message inside the popup and show the container
 Args            : header,body,footer = html code that will be displayed in those 3 areas of the popup
                   x,y                = Position the popup to those coord
                   Those 5 arguments are optional (they can be undefined), and the derived classes may ignore all those arguments, except from body.
 Globals         : none

=cut
*/
	Display: function(body,header,footer,x,y){throw('this is an abstract class');},

/*
=pod

=head2 procedure Close

 Title           : close
 Usage           : o_popup.Close()
 Function        : Close the popup
 Globals         : none

=cut
*/
	Close: function(){throw('this is an abstract class');}
});

/*
=pod

=head1 class LipmPopupDummyClass

 Title           : LipmPopupDummyClass
 Class           : this popup is a fake popup, useful only for developers
 Constructor arg : div : Anything, even nothing, will not be used anyway
 Globals         : none

=cut
*/

LipmPopupDummyClass = Class.create(LipmPopupBaseClass,{
	initialize: function($super,div)
	{
		try
		{
			$super(div);
		}
		catch(e){};
	},
	Display: function(){},
	Close:function(){}
});

/*
=pod

=head1 class LipmPopupSimpleClass

 Title           : LipmPopupSimpleClass
 Class           : this popup is just connected to a <div>...</div>
 Constructor arg : div : the id of the div we'll use as a popup
 Globals         : none

=cut
*/

LipmPopupSimpleClass = Class.create(LipmPopupBaseClass,{
	initialize: function($super,div)
	{
		$super(div);
		this.__bd = this._div.down('.bd');
		this.__hd = this._div.down('.hd');
		this.__ft = this._div.down('.ft');
	},

/*
=pod

=head2 procedure Display

 Title           : Display
 Usage           : o_popup.Display(body,header,footer);
 Function        : Print a message inside the popup and show the container
 Args            : header,body,footer = html code that will be displayed in those 3 areas of the popup
                   x,y                = IGNORED
				   If the popup is connected to a simple <div id="ID_POPUP"></div> container, header and footer are ignored
				   However, the following structure may be more useful: <div id="ID_POPUP"><h1 class="hd"></h1><p class="bd"></p><p class="ft"></p></div>
				   as header will be put inside the "hd" element, bd inside the "bd" element, ft inside the "ft" element
				   except from body.
 Globals         : none

=cut
*/

Display: function(body,header,footer,x,y){
		if (body != undefined)
		{
			if (this.__bd==undefined)
			{
				this._div.update(body);
			}
			else
			{
				this.__bd.update(body);
				if (this.__hd!=undefined && header==undefined) {this.__hd.update(header);};
				if (this.__ft!=undefined && footer!=undefined) {this.__ft.update(footer);};
			}
			this._ObserveLinks();
			this._div.show();
		}
	},
	Close: function(){this._div.hide();}
});

/*
=pod

=head1 class LipmPopupYUITabClass

 Title           : LipmPopupYUITabClass
 Class           : this popup is just connected to a <div>...</div>
 Constructor arg : div : the id of the div we'll use as a popup
                   o_tabview: the tabview we are a tab of
                   index: the index of the tab in this tabview
 Globals         : none

=cut
*/

LipmPopupYUITabClass = Class.create(LipmPopupBaseClass,{
	initialize: function($super,div,o_tabview,index)
	{
		$super(div);
		this.__o_tabview = o_tabview;
		this.__index = index;

		this.__bd = this._div.down('.bd');
		this.__hd = this._div.down('.hd');
		this.__ft = this._div.down('.ft');
	},

/*
=pod

=head2 procedure Display

 Title           : Display
 Usage           : o_popup.Display(body,header,footer);
 Function        : Print a message inside the popup and show the container
 Args            : header,body,footer = html code that will be displayed in those 3 areas of the popup
                   x,y                = IGNORED
                   If the popup is connected to a simple <div id="ID_POPUP"></div> container, header and footer are ignored
                   However, the following structure may be more useful: <div id="ID_POPUP"><h1 class="hd"></h1><p class="bd"></p><p class="ft"></p></div>
                   as header will be put inside the "hd" element, bd inside the "bd" element, ft inside the "ft" element
                   except from body.
 Globals         : none

=cut
*/

Display: function(body,header,footer,x,y){
		if (body != undefined)
		{
			if (this.__bd==undefined)
			{
				this._div.update(body);
			}
			else
			{
				this.__bd.update(body);
				if (this.__hd!=undefined) {this.__hd.update(header);};
				if (this.__ft!=undefined) {this.__ft.update(footer);};
			}
			this._ObserveLinks();
			this.__o_tabview.set('activeIndex',this.__index);
		}
	},
	Close: function(){this._div.hide();}
});

/*
=pod

=head1 class LipmPopupYUIClass

 Title           : LipmPopupYUIClass
 Usage           : This class derives from LipmPopupBaseClass, a YUI panel is encapsulated
 Constructor arg : div        : the id of the div we'll use as a popup
                   resize_flag: if true, there is a resize handle
				   center_flag: if true, the property "fixedcenter" is set
 Globals         : none

=cut
*/

LipmPopupYUIClass = Class.create(LipmPopupBaseClass,{
	initialize: function($super,div,resize_flag,center_flag)
	{
		if (resize_flag==undefined) {resize_flag=false;};
		if (center_flag==undefined) {center_flag=false;};

		$super(div);
		this.__popup = new YAHOO.widget.Panel(div,{
			width:"auto",
			fixedcenter: center_flag,
			close:true,
			visible:false,
			draggable:true,
			underlay:"shadow",
			zIndex:500,			// We select a huge z-index to have a chance to get the popup above every other window
//			constraintoviewport: true
			context: ["showbtn", "tl", "bl"]
		} );
		this.__popup.render();
		if (resize_flag==true)
		{
			this.__resize = new YAHOO.util.Resize(div,{
				handles: ['br'],
				minWidth: 100,
				minHeight: 100,
				maxHeight: 500,
				status:false
			});
			this.__resize.on('resize', function(args){
				var panelHeight = args.height;
				var headerHeight = this.header.offsetHeight; // Content + Padding + Border
				var footerHeight = this.footer.offsetHeight; // Content + Padding + Border
				var bodyHeight = (panelHeight - headerHeight-footerHeight-20);

				YAHOO.util.Dom.setStyle(this.body, 'height', bodyHeight + 'px');

				if (IE_SYNC) {
					// Keep the underlay and iframe size in sync.
					this.sizeUnderlay();

					// Syncing the iframe can be expensive. Disable iframe if you don't need it.
					this.syncIframe();
				}
			},this.__popup,true);
			//	alert(YAHOO.util.Resize.getResizeById(div));
		}
	},
	Display: function(body,header,footer,x,y)
	{
		if (header != undefined) {this.__popup.setHeader(header);}
		if (body   != undefined) {this.__popup.setBody(body);}
		if (footer != undefined) {this.__popup.setFooter(footer);}
		this._ObserveLinks();
		this.__popup.show();
		if (x != undefined && y != undefined) {this.__popup.cfg.setProperty('xy',[x,y]);};
		this.__popup.bringToTop();
	},
	Close: function ()
	{
		this.__popup.hide();
	}
});

/*
=pod

=head1 class LipmNewWindowClass

 Title           : LipmNewWindowclass
 Usage           :
 Constructor arg : link_class : A class name - Any element belonging to this class will be observed if the method Observe is called
                                This is ALSO the name of the window which will be opened by the click event
                   o_attributes: A javascript object, containing all flags that will be passed to window.open
                   blank_win  : If true, the opened window does not have any name (blank)
                                If false (default), the name of theopened window is link_class
                   Example: new LipmWindowClass('WindowSequence',{
                                                       directories: false,
                                                       location: false,
                                                       menubar: false,
                                                       toolbar: false,
                                                       scrollbars: true,
                                                       status: true,
                                                       resize: true,
                                                       copyhistory: true,
                                                       height: 500,
                                                       width: 1000
                                                });
 Globals         : none

=cut
*/
LipmPopupNewWindowClass = Class.create({
		initialize: function(link_class,o_attributes,blank_win)
		{
			if (blank_win==undefined){blank_win=false;};
			this.__class = link_class;
			this.__name  = (blank_win)?'':this.__class;
			if (o_attributes!=undefined && o_attributes!="")
			{
				var h_attributes = $H(o_attributes);
				var a_attributes = $A();
				var a_keys       = h_attributes.keys();
				h_attributes.keys().each(function(k){
						var v = h_attributes.get(k);
						if (v==true)
						{
							a_attributes.push(k + '=Yes');
							return;
						};
						if (v==false)
						{
							a_attributes.push(k + '=No');
							return;
						};
						a_attributes.push(k + '=' + v);
				});
				this.__attributes = a_attributes.join(',');
				this.__attributes = 'config='+this.__attributes;
			}
			else
			{
				this.__attributes = undefined;
			}
		},
/*
=pod

=head2 procedure Observe

 Title           : Observe
 Usage           : o_popup.Observe(top_id);
 Function        : Retrieve all elements belonging to the class this.__class who and who are descendants of top_id
                   If the element is not a <a> tag, retrieve the first a tag above him
                   Declare this.__EvtHandler as handler
 Args            : top_id, if undefined the whole document is explored
 Globals         : none

=cut
*/
        Observe: function(top_id)
		{
			var elt = $(top_id);

			var selector = '.' + this.__class;
			var ThisLipmPopupNewWindowClass = this;
			var a_elements = (elt==null) ? $$(selector) : elt.select(selector);
			a_elements.each(
				function(e){
					Event.observe(e,'click',ThisLipmPopupNewWindowClass.__EvtHandler.bindAsEventListener(ThisLipmPopupNewWindowClass));
				});
		},
/*
=pod

=head2 procedure RegisterUrlComp

 Title           : RegisterUrlComp
 Usage           : o_popup.RegisterurlComp(fct);
 Function        : register a function, this function will be called by __EvtHandler to compute the url to open
                   The registered function must take no argument and return a complete url (http://some.where.com/some.thing?bla=...
 Args            : function a javascript function
 Globals         : none

=cut
*/
        RegisterUrlComp: function(fct)
		{
			this.__url_comp_fct = fct;
		},

/*
=pod

=head2 procedure __EvtHandler

 Title           : __EvtHandler
 Usage           : through an event
 Function        : Open the window, retrieving the url from:
                        - the href element
                   The window name is taken from this.__name, the attribute is taken from this.__attribute
 Args            : evt
 Access          : private
 Globals         : none

=cut
*/
		__EvtHandler: function(evt)
		{
			var elt  = evt.element();
			if (elt.tagName != 'A'){ elt = elt.up('a');};
			if (elt==undefined){return;};
			evt.stop();
			var url = (this.__url_comp_fct) == undefined ? elt.href : this.__url_comp_fct.call();
			if( this.__attributes==undefined )
			{
				var win = window.open(url,this.__name);
			}
			else
			{
				win = window.open(url,this.__name,this.__attributes);
			}
			win.focus();
		},
/*
=pod

=head2 procedure Open

 Title           : Open
 Usage           : var w = o_obj.Open(url);
 Function        : Open the window, pointing the window to the passed url
                   The window name is taken from this.__name, the attribute is taken from this.__attribute
 Args            : url
 Access          : public
 Globals         : none

=cut
*/
		Open: function(url)
		{
			var win = (this.__attributes==undefined)? window.open(url,this.__name) : window.open(url,this.__name,this.__attributes);
			win.focus();
			return win;
		}
});

/*
=pod

=head1 COPYRIGHT NOTICE

This software is governed by the CeCILL license under French law - www.cecill.info

=cut
*/


