diff --git a/product/ERP5Form/PlanningBox.py b/product/ERP5Form/PlanningBox.py
new file mode 100755
index 0000000000000000000000000000000000000000..6820ef504301e752560d5ce51650e06daa978b5b
--- /dev/null
+++ b/product/ERP5Form/PlanningBox.py
@@ -0,0 +1,1210 @@
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Jonathan Loriette <john@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+import string, types, sys
+from Form import BasicForm
+from Products.Formulator.Field import ZMIField
+from Products.Formulator.DummyField import fields
+from Products.Formulator.MethodField import BoundMethod
+from DateTime import DateTime
+from Products.Formulator import Widget, Validator
+from Products.Formulator.Errors import FormValidationError, ValidationError
+from Selection import Selection, DomainSelection
+from SelectionTool import makeTreeList
+import OFS
+from AccessControl import ClassSecurityInfo
+from zLOG import LOG
+from copy import copy
+from Acquisition import aq_base, aq_inner, aq_parent, aq_self
+
+from Products.Formulator.Form import BasicForm
+
+from Products.ERP5Type.Utils import getPath
+from Products.ERP5Type.Document import newTempBase
+from Products.CMFCore.utils import getToolByName
+
+
+class PlanningBoxValidator(Validator.StringBaseValidator):
+    def validate(self, field, key, REQUEST):
+        try:
+          for lang in list_value.keys():
+            list_value[lang] = int(list_value[lang])
+        except ValueError:
+            self.raise_error('not an integer', field)
+            
+        return list_value
+   
+PlanningBoxValidatorInstance=PlanningBoxValidator()        
+
+def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_method,
+                     here,report_root_list,y_axis_width,width_line,space_line,
+                     height_global_div,height_header,height_axis_x,form,current_top):
+  report_sections = []
+  section_index = 0
+  if len(report_sections) > section_index:
+    current_section = report_sections[section_index]
+  elif len(report_sections):
+    current_section = report_sections[0]
+  else:
+    current_section = None
+  filtered_meta_types = map(lambda x: x[0], meta_types)
+  params = selection.getParams()
+  sort = field.get_value('sort')
+  kw=params
+  report_depth = REQUEST.get('report_depth', None)
+  is_report_opened = REQUEST.get('is_report_opened', selection.isReportOpened())
+  
+  portal_categories = getattr(form, 'portal_categories', None)
+  if 'select_expression' in kw:
+    del kw['select_expression']
+  if hasattr(list_method, 'method_name'):
+    list_method = here.objectValues
+    kw = copy(params)
+    kw['spec'] = filtered_meta_types
+  elif list_method in (None, ''): # Use current selection
+    # Use previously used list method
+    list_method = None
+  select_expression = ''
+  default_selection_report_path = report_root_list[0][0].split('/')[0]
+  if default_selection_report_path in portal_categories.objectIds() or \
+    (portal_domains is not None and default_selection_report_path in portal_domains.objectIds()):
+    pass
+  else:
+    default_selection_report_path = report_root_list[0][0]          
+  selection_report_path = selection.getReportPath(default = (default_selection_report_path,))
+  if report_depth is not None:
+    selection_report_current = ()
+  else:
+    selection_report_current = selection.getReportList()
+  report_tree_list = makeTreeList(here, form, None,selection_report_path,None,0, 
+                                  selection_report_current, form.id, selection_name, 
+                                  report_depth,is_report_opened, sort_on=selection.sort_on)
+  # Update report list if report_depth was specified
+  if report_depth is not None:
+    report_list = map(lambda s:s[0].getRelativeUrl(), report_tree_list)
+    selection.edit(report_list=report_list)
+  report_sections = []
+  
+  list_object = []
+  nbr_line=0
+  object_list=[]    
+  indic_line=0 
+  index_line = 0  
+  for s in report_tree_list:      
+    selection.edit(report = s.getSelectDomainDict())            
+    
+    if s.getIsPureSummary():
+      original_select_expression = kw.get('select_expression')
+      kw['select_expression'] = select_expression
+      selection.edit( params = kw )
+      if original_select_expression is None:
+        del kw['select_expression']
+      else:
+        kw['select_expression'] = original_select_expression
+    
+    if s.getIsPureSummary():
+      stat_result = {}
+      index = 1
+      report_sections += [s]
+      nbr_line+=1       
+    else:
+      # Prepare query
+      selection.edit( params = kw )
+      if list_method not in (None, ''):
+        object_list = selection(method = list_method, context=here, REQUEST=REQUEST,
+                                s=s, object_list= object_list)          
+      else:
+        object_list = here.portal_selections.getSelectionValueList(selection_name,
+                                                          context=here, REQUEST=REQUEST)
+      
+    selection.edit(report=None)
+  index = 0
+  # we start to build our line object structure right here.
+  for l in report_sections:
+    stat_result = {}
+    stat_context = l.getObject().asContext(**stat_result)
+    stat_context.domain_url = l.getObject().getRelativeUrl()
+    stat_context.absolute_url = lambda x: l.getObject().absolute_url()     
+    url=getattr(stat_context,'domain_url','')
+      
+    if l.getDepth() == 0:
+      paternity = 0
+      if len(l.getObject().objectValues())!=0:
+        paternity = 1
+    
+      height=(height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)
+      line = Line(title=l.getObject().getTitle(),
+                   name='fra' + str(indic_line),
+                   begin=y_axis_width,
+                   width=width_line,
+                   height=height,
+                   top=current_top,color='#ffffff',
+                   paternity=paternity,url=url)    
+      list_object.append(line)
+      
+
+      if paternity == 0:  
+        current_top=current_top+((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)) + (space_line)
+
+      else:
+        if (index+1)<=(len(report_sections)-1): 
+          if report_sections[index+1].getDepth()==0:
+            #current_top=current_top+((height_global_div-height_header-height_axis_x)/float(nbr_line)) + (space_line) 
+            current_top=current_top+((height_global_div-height_header-height_axis_x-(((nbr_line-1))*space_line))/float(nbr_line))+ (space_line)    
+             
+          else:
+           
+            current_top=current_top+((height_global_div-height_header-height_axis_x-(((nbr_line-1))*space_line))/float(nbr_line)) 
+
+    else:
+      current_index = 0      
+      while l.getDepth() == report_sections[index-current_index].getDepth():
+        current_index += 1
+      if report_sections[index-current_index].getDepth() == 0:
+        current_top=list_object[len(list_object)-1].createLineChild(report_sections,field,current_top,y_axis_width,width_line,space_line,height_global_div,height_header,height_axis_x,nbr_line,index,url)
+        
+      else : # in this case wee add a soon to a soon
+        depth=0 
+        current_soon=list_object[len(list_object)-1]
+        while depth != (l.getDepth()-1):
+          current_soon=list_object[len(list_object)-1].soon[len(list_object[len(list_object)-1].soon)-1]
+          depth+=1
+        current_top=current_soon.createLineChild(report_sections,field,current_top,y_axis_width,width_line,space_line,height_global_div,height_header,height_axis_x,nbr_line,index,url)    
+    index += 1
+    indic_line+=1
+  return (list_object,nbr_line,report_sections)
+
+    
+def createGraphicCall(current_line,graphic_call):
+  """ create html code of children used by graphic library to know which block can be moved"""
+  
+  for i in current_line.soon:
+    for j in i.content:
+      if j.types=='activity':
+        graphic_call+='\"'+j.name+'\",'
+      elif j.types=='info':
+        graphic_call+='\"'+j.name+'\"+NO_DRAG,'   
+    if i.soon!=[]: # case of a soon which has soons...
+      graphic_call+=createGraphicCall(i,graphic_call)        
+  return graphic_call
+  
+  
+       
+        
+#class planningboxwidget *********************************
+class PlanningBoxWidget(Widget.Widget):
+    property_names = Widget.Widget.property_names +\
+                     ['height_header', 'height_global_div','height_axis_x', 'width_line','space_line','list_method','report_tree','report_root_list','selection_name','portal_types','meta_types','sort','title_line','y_unity','y_axis_width','y_range','x_range','x_axis_script_id','x_start_bloc','x_stop_bloc','y_axis_method','info_block_method','security_index']
+    
+    default = fields.TextAreaField('default',
+                                title='Default',
+                                description=(
+        "Default value of the text in the widget."),
+                                default="",
+                                width=20, height=3,
+                                required=0)	     
+     
+                             
+    height_header = fields.IntegerField('height_header',
+                                title='height of the header (px):',
+                                description=(
+        "value of the height of the header, required"),
+                                default=50,
+                                required=1)    
+                                                                             
+    height_global_div = fields.IntegerField('height_global_div',
+                                title='height of the graphic (px):',
+                                description=(
+        "value of the height of the graphic, required"),
+                                default=700,
+                                required=1) 
+    height_axis_x = fields.IntegerField('height_axis_x',
+                                title='height of X-axis (px):',
+                                description=(
+        "value of the height of X-axis"),
+                                default=50,
+                                required=1) 	
+                                
+    width_line = fields.IntegerField('width_line',
+                                title='width of the graphic (px):',
+                                description=(
+        "value of width_line, required"),
+                                default=1000,
+                                required=1) 
+    space_line = fields.IntegerField('space_line',
+                                title='space between each line of the graphic (px):',
+                                description=(
+        "space between each line of the graphic,not required"),
+                                default=10,
+                                required=0)   
+                                
+                                
+    report_tree = fields.CheckBoxField('report_tree',
+                                 title='Report Tree',
+                                 description=('Report Tree'),
+                                 default='',
+                                 required=0)
+
+
+
+    report_root_list = fields.ListTextAreaField('report_root_list',
+                                 title="Report Root",
+                                 description=(
+        "A list of domains which define the possible root."),
+                                 default=[],
+                                 required=0)
+  
+    selection_name = fields.StringField('selection_name',
+                                 title='Selection Name',
+                                 description=('The name of the selection to store'
+                                              'params of selection'),
+                                 default='',
+                                 required=0)
+                                 
+    portal_types = fields.ListTextAreaField('portal_types',
+                                 title="Portal Types",
+                                 description=(
+        "Portal Types of objects to list. Required."),
+                                 default=[],
+                                 required=0)
+                                 
+    meta_types = fields.ListTextAreaField('meta_types',
+                                 title="Meta Types",
+                                 description=(
+        "Meta Types of objects to list. Required."),
+                                 default=[],
+                                 required=0)
+                                                              
+    sort = fields.ListTextAreaField('sort',
+                                 title='Default Sort',
+                                 description=('The default sort keys and order'),
+                                 default=[],
+                                 required=0)
+  
+                                 
+    list_method = fields.MethodField('list_method',
+                                 title='List Method',
+                                 description=('The method to use to list'
+                                             'objects'),
+                                 default='',
+                                 required=0)                             
+
+                                                             
+    title_line = fields.StringField('title_line',
+                                title='specific method which fetches the title of each line: ',
+                                description=('specific method for inserting title in line'),
+                                default='',
+                                required=0)                            
+
+                                
+    y_unity = fields.StringField('y_unity',
+                                 title='Unity in Y-axis:',
+                                 description=('The unity in Y-axis,not required'),
+                                 default='',
+                                 required=0)
+
+    y_axis_width = fields.IntegerField('y_axis_width',
+                                title='width of Y-axis (px):',
+                                description=(
+        "width of Y-axis, required"),
+                                default=200,
+                                required=1) 
+    
+    y_range = fields.IntegerField('y_range',
+                                title='number of range of Y-axis :',
+                                description=(
+        "Number of Range of Y-axis, not required"),
+                                default=5,
+                                required=0) 
+ 
+    x_range = fields.StringField('x_range',
+                                 title='range of X-Axis:',
+                                 description=('Nature of the subdivisions of X-Axes, not Required'),
+                                 default='Day',
+                                 required=0)	
+ 
+    x_axis_script_id = fields.StringField('x_axis_script_id',
+                                 title='script for building the X-Axis:',
+                                 description=('script for building the X-Axis'),
+                                 default='',
+                                 required=0)	
+
+    x_start_bloc = fields.StringField('x_start_bloc',
+                                 title='specific method which fetches the data for the beginning of a block:',
+                                 description=('Method for building X-Axis such as getstartDate'
+                                              'objects'),
+                                 default='getStartDate',
+                                 required=0)	
+    
+    x_stop_bloc = fields.StringField('x_stop_bloc',
+                                 title='specific method which fetches the data for the end of each block',
+                                 description=('Method for building X-Axis such getStopDate'
+                                              'objects'),
+                                 default='',
+                                 required=0)	
+
+ 
+    y_axis_method = fields.StringField('y_axis_method',
+                                 title='specific method of data type for creating Y-Axis',
+                                 description=('Method for building Y-Axis'
+                                              'objects'),
+                                 default='',
+                                 required=0) 
+  
+    info_block_method = fields.StringField('info_block_method',
+                                 title='specific method for inserting infos in Block',
+                                 description=('Method for inserting info'
+                                              'objects'),
+                                 default='',
+                                 required=0)
+     
+    security_index = fields.IntegerField('security_index',
+                                title='variable depending of the type of web browser :',
+                                description=("This variable is used because the rounds of each web browser seem to work differently"),
+                                default=2,
+                                required=0) 	 
+                                                                                       
+    def render_css(self, field, key, value, REQUEST):
+  
+        # DATA DEFINITION #############################################
+        height_header = field.get_value('height_header')
+        height_global_div = field.get_value('height_global_div')
+        height_axis_x=field.get_value('height_axis_x')
+        width_line = field.get_value('width_line')
+        space_line = field.get_value('space_line')
+        selection_name = field.get_value('selection_name')
+        security_index = field.get_value('security_index')
+        y_unity = field.get_value('y_unity')
+        y_axis_width = field.get_value('y_axis_width')
+        y_range = field.get_value('y_range')
+        portal_types= field.get_value('portal_types')
+        meta_types = field.get_value('meta_types')
+        x_range=field.get_value('x_range')
+        here = REQUEST['here']
+        list_method = field.get_value('list_method')
+        report_tree = field.get_value('report_tree')
+        report_root_list = field.get_value('report_root_list')
+        y_axis_method=field.get_value('y_axis_method')
+        script=getattr(here,field.get_value('x_axis_script_id'),None)
+        info_block_method = getattr(here,field.get_value('info_block_method'),None)
+        object_start_method_id = field.get_value('x_start_bloc')
+        object_stop_method_id= field.get_value('x_stop_bloc')
+        form = field.aq_parent
+
+        x_occurence=[] # contains datas of start and stop of each block like this [ [ [x1,x2],[x1,x2] ],[ [x1,x2],[x1,x2] ],.....] it is not directly coordinate but datas.                    
+        x_axe=[] # will contain what wee need to display in X-axis. contains: (data used for construction, display of x-axis)
+        yrange=[] # we store the value in Y-axis of each block 
+        nbr=1
+        y_max=1      
+        current_top=height_header
+        total=[]
+        list_object=[] #in this list we store all the objects of type Line
+        giant_string='' #will contain all the html code.
+        report_sections=[]
+        # END DATA DEFINITION ###########################################                        
+        # we fetch fold/unfold datas ######################
+        #here.portal_selections.setSelectionFor(selection_name, None)#put selection to null
+        selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST)
+        default_params = {}
+        sort = ()
+        if selection is None:
+          selection = Selection(params=default_params, default_sort_on = sort)
+        domain_list = list(selection.getDomainList())
+        here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST)
+        ########################
+
+        #we build line ***************************
+        (list_object,nbr_line,report_sections)=createLineObject(meta_types,selection,selection_name,field,REQUEST,list_method,here,report_root_list,y_axis_width,width_line,space_line,height_global_div,height_header,height_axis_x,form,current_top)
+        
+        # end build line ####################################################
+        
+         #we build x_occurence (used for the range in x-Axis ##################################
+        for o in report_sections: 
+          method_start = getattr(o.getObject(),object_start_method_id,None)
+          method_stop= getattr(o.getObject(),object_stop_method_id,None)
+          block_begin = method_start()
+          if method_stop!=None:
+            block_stop= method_stop()
+          else:
+            block_stop=None
+          x_occurence.append([block_begin,block_stop])
+        x_axe=script(x_occurence,x_range) #we call this script for the range in X-Axis
+        ##################################################     
+         
+         # we add mobile block to the line object ###################################
+        indic_line=0 
+        #for o report_sections:
+        for o in list_object:
+          if list_object != []:
+            list_object[indic_line].insertActivityBlock(report_sections[indic_line].getObject(),object_start_method_id,object_stop_method_id,x_axe,field)
+            indic_line+=1
+        # #############################################################
+        # at this point list_object contains our tree of datas. Then wee add others object for the graphic.
+
+        #one constructs the vertical dotted line **********************
+        marge_left=y_axis_width+width_line/float(len(x_axe[1]))
+        for i in list_object:
+          i.appendVerticalDottedLine(x_axe,width_line,marge_left)
+        #*************************************************************    
+
+            
+        #one constructs the maximum horizontal dotted line 10px under the top of the line***************
+        maximum_y=y_max
+        marge_top=10 
+        if y_range!=0:  
+          for i in list_object:  
+            i.appendHorizontalDottedLine(marge_top,maximum_y,height_global_div,height_header,height_axis_x,nbr_line,y_range,y_max,current_section)
+            #end construct of horizontal dotted line ********************************************************
+   
+
+        # we construct y-axis   ******************************
+        way=[]    
+        y=[]
+        level=0
+        current_top=height_header
+        idx=0
+        for i in list_object:
+          current_top=i.buildYtype(way,y,level,y_axis_width,height_global_div,height_header,height_axis_x,nbr_line,current_top,space_line,y_max,y_range,y_unity,selection_name,form)  
+          
+          #current_top=y[len(y)-1].top+((height_global_div-height_header-height_axis_x)/float(nbr_line))+space_line
+          
+          current_top=y[len(y)-1].top+((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line))+space_line
+
+          
+          idx+=1
+        list_object=y+list_object #we need to add the y-axis block at the beginning of our structure otherwise the display is not correct
+        #************************end construct y-axis 	 
+
+        
+        #build X axis ########################################
+        list_object.append(Line('','axis_x',y_axis_width,width_line,height_axis_x,current_top-space_line)) 
+        list_object[len(list_object)-1].createXAxis(x_axe,width_line,y_axis_width)
+       #***************************
+        
+        SESSION = REQUEST.SESSION
+        SESSION.set('total',list_object)  
+        SESSION.set('width_line',width_line) 
+        SESSION.set('height_global', height_global_div)
+        SESSION.set('y_axis_width', y_axis_width)
+        SESSION.set('report_tree',report_tree)
+        SESSION.set('report_root_list',report_root_list)
+        SESSION.set('selection_name',selection_name)
+        for i in list_object:
+          giant_string+=i.render_css(y_axis_width,security_index)   
+        return giant_string
+      
+        
+                
+       
+    def render(self,field, key, value, REQUEST):
+        here = REQUEST['here']
+        portal_url= here.portal_url()
+        SESSION = REQUEST.SESSION
+        total = SESSION.get('total')  
+        width_line=SESSION.get('width_line')
+        height_global_div=SESSION.get('height_global')
+        y_axis_width=SESSION.get('y_axis_width')
+        report_tree=SESSION.get('report_tree')
+        report_root_list=SESSION.get('report_root_list')
+        selection_name=SESSION.get('selection_name')
+        giant_string='<input type=\"hidden\" name=\"list_selection_name\" value='+selection_name+' />\n'
+
+        giant_string+='<div id=\"global_block\" style=\"position:absolute;width:'+str(width_line+y_axis_width)+'px;height:'+str(height_global_div)+'px;background:#d5e6de;margin-left:-99px;border-style:solid;border-color:#000000;border-width:1px;margin-top:-21px\">\n' 
+        
+        #header of the graphic******************************************
+        giant_string+='<div id=\"header\" style=\"position:absolute;width:'+str(width_line+y_axis_width)+'px;height:'+str(height_global_div)+'px;background:#d5e6de;margin-left:20px;border-style:solid;border-color:#000000;border-width:1px;margin-top:1px\">'
+        
+        ##########################report tree
+        # Create the header of the table with the name of the columns
+        # Create also Report Tree Column if needed
+        if report_tree:
+          selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST)
+          selection_report_path = selection.getReportPath()
+
+          report_tree_options = ''
+          for c in report_root_list:
+            if c[0] == selection_report_path:
+              report_tree_options += """<option selected value="%s">%s</option>\n""" % (c[0], c[1])
+            else:
+              report_tree_options += """<option value="%s">%s</option>\n""" % (c[0], c[1])
+          report_popup = """<select name="report_root_url"
+onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
+        %s</select></div>""" % (here.getUrl(),report_tree_options)
+          giant_string += report_popup
+        else:
+          report_popup = ''
+        ######################################
+
+        for i in range(0,len(total)):
+          giant_string+=total[i].render(portal_url,y_axis_width)    
+      ###################"  
+    
+        giant_string+='<div id=\"lefttop\" style=\"position:absolute;width:5px;height:5px;background:#a45d10\"></div>\n'
+        giant_string+='<div id=\"righttop\" style=\"position:absolute;width:5px;height:5px;background:#a45d10"></div>\n'
+        giant_string+='<div id=\"rightbottom\" style=\"position:absolute;width:5px;height:5px;background:#a45d10\"></div>\n'
+        giant_string+='<div id=\"leftbottom\" style=\"position:absolute;width:5px;height:5px;background:#a45d10\"></div>\n'
+        giant_string+='<script type=\"text/javascript\">\n SET_DHTML('
+        
+        
+        for i in range(0,len(total)):
+          graphic_call=''
+          for j in total[i].content:
+            if j.types=='activity':
+              giant_string+='\"'+j.name+'\",'
+            elif j.types=='info':
+              giant_string+='\"'+j.name+'\"+NO_DRAG,'
+      
+          current_object=total[i]
+
+          if current_object.soon!=[]:  
+            giant_string+=createGraphicCall(current_object,graphic_call)     
+      
+        giant_string+='\"lefttop\"+CURSOR_NW_RESIZE, \"righttop\"+CURSOR_NE_RESIZE, \"rightbottom\"+CURSOR_SE_RESIZE, \"leftbottom\"+CURSOR_SW_RESIZE);\n'
+        giant_string+='</script>\n </div> '
+        return giant_string  
+#***************************************************          
+          
+
+
+# class line **************************************
+class Line:
+  def __init__(self,title='',name='',begin=0,width=0,height=0,top=0,color='',soon=None,y_type='none',paternity=0,url=''):  
+    if soon is None:
+     soon = []
+    self.title=title
+    self.name=name
+    self.begin=begin
+    self.width=width
+    self.height=height
+    self.top=top
+    self.content=[]
+    self.color=color
+    self.soon=soon
+    self.y_type=y_type
+    self.paternity=paternity
+    self.url=url
+   
+
+  def render(self,portal_url,y_axis_width):
+    """ creates "pure" html code of the line, its Block, its soon """
+    html_render='<div id=\"'+self.name+'\"></div>\n'
+    for j in self.content:
+      if j.types=='activity':
+        if ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width): #checks if the block is too large for the end of the line if it is the case, one cuts the block
+          html_render+='<div id=\"'+j.name+'\" ondblclick=\"showGrips()\" onclick=\"dd.elements.'+j.name+'.resizeTo('+str(round(j.width*self.width))+','+ str(j.height*(self.height-10))+') \">'
+        elif ((self.begin+j.begin*self.width) < self.begin): #checks if the block starts before the beginning of the line
+          html_render+='<div id=\"'+j.name+'\" ondblclick=\"showGrips()\" onclick=\"if (dd.elements.'+j.name+'.moved==0){dd.elements.'+j.name+'.moveBy('+str(round(j.begin*self.width))+',0);dd.elements.'+j.name+'.resizeTo('+str(round(j.width*self.width))+','+ str(j.height*(self.height-10))+');dd.elements.'+j.name+'.moved=1} \">'  # "done" is used because otherwise everytime we move the block it will execute moveby()
+        else:
+          html_render+='<div id=\"'+j.name+'\" ondblclick=\"showGrips()\">'      
+  
+        html_render+=j.render(self.width,self.height,portal_url,self.begin,y_axis_width)   # we add info Block inside the div   
+        html_render+='</div>\n'
+      elif j.types!='info':
+        html_render+='<div id=\"'+j.name+'\">'+str(j.text)+'</div>\n'  
+    
+
+    if self.soon!=[]:
+      for i in self.soon:
+        html_render+=i.render(portal_url,y_axis_width)
+      
+    return html_render    
+    
+
+    
+  def render_css(self,y_axis_width,security_index):
+    css_render='#'+self.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-width:1px;\n'
+    if self.color!='':
+      css_render+='background:'+str(self.color)+';\n'
+    css_render+='height:'+str(self.height)+'px;\n'
+    css_render+='margin-left:'+str(self.begin)+'px;\n'
+    css_render+='margin-top:'+str(self.top)+'px;\n'
+
+    if self.y_type=='father1':
+      css_render+='border-bottom-width:0px;'
+    elif self.y_type=='soon1':
+      css_render+='border-top-width:0px;\nborder-bottom-width:0px;\n'    
+    elif self.y_type=='soon2':
+      css_render+='border-top-width:0px;'
+    css_render+='width:'+str(self.width)+'px;\n}'
+      
+    
+    for j in self.content: #we generate block's css
+      if j.types=='activity':
+        css_render+='#'+j.name+'{position:absolute;\nbackground:#bdd2e7;\nborder-style:solid;\nborder-color:#53676e;\nborder-width:1px;\n'
+        css_render+='height:'+str((j.height*(self.height-10))-security_index)+'px;\n'     #-10 because wee don't want a block sticked to border-top of the line
+        # text=str('%.2f' %maximum_y)+y_unity   
+
+        if ((self.begin+j.begin*self.width) < self.begin): #checks if the block starts before the beginning of the line
+          css_render+='margin-left:'+str(self.begin)+'px;\n' 
+          css_render+='width:'+str((j.width*self.width+j.begin*self.width))+'px;\n' 
+        elif ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width): #checks if the block is too large for the end of the line. if it is the case, one cuts the block
+          css_render+='width:'+str(round(j.width*self.width)-((self.begin+j.begin*self.width+j.width*self.width)-(self.width+y_axis_width)))+'px;\n'
+
+          css_render+='margin-left:'+str(round(self.begin+j.begin*self.width))+'px;\n' 
+        else:  
+          css_render+='width:'+str(round(j.width*self.width))+'px;\n'
+          css_render+='margin-left:'+str(round(self.begin+j.begin*self.width))+'px;\n' 
+
+        css_render+='margin-top:'+str(self.top+10+j.marge_top*(self.height-10))+'px;}\n'  
+        css_render+=j.render_css(self.width,self.height-10,self,y_axis_width)  # we add info Block inside the div       
+        
+      elif j.types=='text_x' : 
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-width:1px;\n'
+        css_render+='margin-left:'+str(j.begin)+'px;\n' 
+        css_render+='margin-top:'+str(round(1+self.top+self.height/2))+'px;}\n'
+        
+      elif j.types=='text_y':
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-width:1px;\n'
+        css_render+='margin-left:'+str(self.width/4)+'px;\n' 
+        css_render+='margin-top:'+str(round(1+self.top+self.height/2))+'px;\n'
+        css_render+='border-width:0px;}\n'
+
+
+      elif j.types=='vertical_dotted':
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:dotted;\nborder-color:#53676e;\nborder-left-width:1px;\nborder-right-width:0px;\nborder-top-width:0px;\nborder-bottom-width:0px;\n'
+        css_render+='margin-left:'+str(j.begin)+'px;\n' 
+        css_render+='height:'+str(self.height)+'px;\n'
+        css_render+='margin-top:'+str(1+round(self.top))+'px;}\n' 
+
+      elif j.types=='horizontal_dotted': 
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:dotted;\nborder-color:#53676e;\nborder-left-width:0px;\nborder-right-width:0px;\nborder-top-width:1px;\nborder-bottom-width:0px;\n'
+        css_render+='margin-left:'+str(self.begin)+'px;\n' 
+        css_render+='height:1px;\n'
+        css_render+='margin-top:'+str(self.top+j.marge_top)+'px;' 
+        css_render+='width:'+str(self.width)+'px;}\n'
+
+      elif j.types=='y_coord':
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nfont-size:9px;\nborder-width:0px;\n'
+        css_render+='margin-left:'+str(self.width-(len(j.text)*5))+'px;\n'  #x6 because this is the appropriate width for our font (9px), maybee need to be parameter
+        css_render+='margin-top:'+str(self.top+j.marge_top)+'px;}\n'
+
+      elif j.types=='vertical':
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-left-width:1px;\nborder-right-width:0px;\nborder-top-width:0px;\nborder-bottom-width:0px;\n'
+        css_render+='margin-left:'+str((self.width/4)+j.begin)+'px;\n'
+        css_render+='height:'+str(j.height)+'px;\n'
+        css_render+='margin-top:'+str(round(self.top)-self.height/2+13)+'px;}\n'
+
+      elif j.types=='horizontal':
+        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-left-width:0px;\nborder-right-width:0px;\nborder-top-width:1px;\nborder-bottom-width:0px;\n'
+        css_render+='margin-left:'+str((self.width/4)+j.begin)+'px;\n'
+        css_render+='width:16px;\n'
+        css_render+='height:1px; \n'
+        # css_render+='margin-top:'+str(round(self.top)-self.height/2+13)+'px;}\n'	
+        css_render+='margin-top:'+str(round(1+self.top+self.height/2))+'px;}\n'
+    
+    if self.soon!=[]:
+      for i in self.soon:
+        css_render+=i.render_css(y_axis_width,security_index);
+
+    return css_render      
+
+    
+
+  def addBlock(self,name,block):
+    self.content.append(Block('activity',name,block[0],block[1],block[2],'',block[3],block[4]))
+    
+  def addBlockInfo(self,name):
+    self.content.append(Block('info',name,0,0,0,''))
+    
+  def addBlockTextY(self,name,text):
+    self.content.append(Block('text_y',name,0,0,0,text))  
+  
+  def addBlockCoordY(self,name,text,marge_top):
+    self.content.append(Block('y_coord',name,0,0,0,text,{},marge_top))  
+    
+  def addBlockTextX(self,name,begin,text):
+    self.content.append(Block('text_x',name,begin,0,0,text))    
+    
+  def addBlockDottedVert(self,name,begin):
+    self.content.append(Block('vertical_dotted',name,begin,0,0,''))  
+    
+  def addBlockDottedHoriz(self,name,marge_top):
+    self.content.append(Block('horizontal_dotted',name,0,0,0,'',{},marge_top))   
+  
+  def addBlockVertical(self,name,marge_top,height,marge_left):
+     self.content.append(Block('vertical',name,marge_left,0,height,'',{},marge_top)) 
+     
+  def addBlockHorizontal(self,name,marge_top,height,marge_left):
+     self.content.append(Block('horizontal',name,marge_left,0,height,'',{},marge_top))    
+         
+
+ 
+      
+    
+  def appendVerticalDottedLine(self,x_axe,width_line,marge_left):
+    current_marge=marge_left
+    indic=0
+    for j in x_axe[1]:
+      nameblock='Block_vert_'+self.name+str(indic)
+      self.addBlockDottedVert(nameblock,current_marge)
+      current_marge+=width_line/float(len(x_axe[1]))   
+      indic+=1
+      
+    if self.soon!=[]:
+      for i in self.soon:
+        i.appendVerticalDottedLine(x_axe,width_line,marge_left) 
+      
+ 
+
+ 
+  def buildYtype(self,way,y,level,y_axis_width,height_global_div,height_header,height_axis_x,nbr_line,current_top,space_line,y_max,y_range,y_unity,selection_name,form): 
+    """ used for determining the type of each part of y axis taking into account father and children
+       'way' is a list whichs allows to determinate if the current block is a type 'soon1' or 'soon2' """
+    report_url=self.url
+    if level==0:
+      name='axis'+str(self.name)
+      if self.soon!=[]:
+        y.append(Line('',name,1,y_axis_width,((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),current_top,'',[],'father1'))
+      else:
+        y.append(Line('',name,1,y_axis_width,((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),current_top,'',[],'father2'))
+        
+      if self.paternity==1:
+        if self.soon!=[]:
+          y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/foldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">-'+self.title+'</a>')
+        else:
+          y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/unfoldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">+'+self.title+'</a>')
+          
+
+      else:
+        y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+self.title)
+      
+      #one constructs the indicators
+      if y_range!=0:
+        y[len(y)-1].createIndicators(y_unity,y_range,y_max,height_global_div,height_header,height_axis_x,nbr_line)
+      
+      if self.soon!=[]:
+        level+=1
+        for j in range(0,len(self.soon)):
+          if j==(len(self.soon)-1):
+            way.append(1)
+          else:
+            way.append(0)
+          current_top+=((height_global_div-height_header-height_axis_x)/float(nbr_line))  
+         
+          current_top=self.soon[j].buildYtype(way,y,level,y_axis_width,height_global_div,height_header,height_axis_x,nbr_line,current_top,space_line,y_max,y_range,y_unity,selection_name,form)
+          del way[len(way)-1]
+  
+    else:
+      if self.soon!=[]:
+        name=str(self.name)
+        for num in way:
+          name=name+str(num)
+        y.append(Line('',name,1,y_axis_width,((height_global_div-height_header-height_axis_x)/float(nbr_line)),current_top,'',[],'soon1'))
+
+        if self.paternity==1:
+          if self.soon!=[]:
+            y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/foldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">-'+self.title+'</a>')
+          else:
+            y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/unfoldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">+'+self.title+'</a>') 
+        else:
+          y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+self.title)
+
+        # one constructs the stick
+        y[len(y)-1].addBlockVertical('stickVer'+name,current_top-((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),(height_global_div-height_header-height_axis_x)/float(nbr_line),3*level*6-18) #6 is the width of the standart font, maybe a future parameter
+        y[len(y)-1].addBlockHorizontal('stickHor'+name,current_top-((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),(height_global_div-height_header-height_axis_x)/float(nbr_line),3*level*6-18) 
+        
+        #one constructs the indicators
+        if y_range!=0:
+          y[len(y)-1].createIndicators(y_unity,y_range,y_max,height_global_div,height_header,height_axis_x,nbr_line)
+        level+=1
+        for j in range(0,len(self.soon)):
+          current_top+=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line))
+          if j==(len(self.soon)-1):
+            way.append(1)
+          else:
+            way.append(0)
+          current_top=self.soon[j].buildYtype(way,y,level,y_axis_width,height_global_div,height_header,height_axis_x,nbr_line,current_top,space_line,y_max,y_range,y_unity,selection_name,form)
+          del way[len(way)-1]
+  
+      else:
+        name=str(self.name)
+        test='true'
+        for num in way:
+          name=name+str(num)
+          if num==0:
+            test='false'
+        if test=='true':
+          y.append(Line('',name,1,y_axis_width,((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),current_top,'',[],'soon2'))
+        else:
+          y.append(Line('',name,1,y_axis_width,((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),current_top,'',[],'soon1'))
+          
+
+        if self.paternity==1:
+          if self.soon!=[]:
+            y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/foldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">-'+self.title+'</a>')
+          else:
+            y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+'<a href="portal_selections/unfoldReport?report_url='+report_url+'&form_id='+form.id+'&list_selection_name='+selection_name+'">+'+self.title+'</a>')
+            
+        else:
+          y[len(y)-1].addBlockTextY('ytext'+name,str(3*'&nbsp '*level)+self.title)  
+  
+        # one constructs the sticks
+        y[len(y)-1].addBlockVertical('stickVer'+name,current_top-((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),(height_global_div-height_header-height_axis_x)/float(nbr_line),3*level*6-18)  
+        y[len(y)-1].addBlockHorizontal('stickHor'+name,current_top-((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line)),(height_global_div-height_header-height_axis_x)/float(nbr_line),3*level*6-18) 
+        
+        #one constructs the indicators   
+        if y_range!=0:
+          y[len(y)-1].createIndicators(y_unity,y_range,y_max,height_global_div,height_header,height_axis_x,nbr_line)
+    return current_top      
+
+
+  def createIndicators(self,y_unity,y_range,y_max,height_global_div,height_header,height_axis_x,nbr_line):
+    #one constructs the indicators
+    maximum_y=y_max
+    marge_top=0
+    indic=0
+    #while maximum_y>=(y_max/float(y_range)):
+    while maximum_y>=0:
+      nameblock='Block_'+self.name+str(indic)
+      text=str('%.2f' %maximum_y)+y_unity    
+      self.addBlockCoordY(nameblock,text,marge_top) 
+      maximum_y=maximum_y-(y_max/float(y_range)) 
+      marge_top+=(((height_global_div-height_header-height_axis_x)/float(nbr_line))-10)/y_range 
+      indic+=1
+ ###############################
+    
+
+  def appendHorizontalDottedLine(self,marge_top,maximum_y,height_global_div,height_header,height_axis_x,nbr_line,y_range,y_max): 
+    current_top=marge_top
+    max_y=maximum_y
+    indic=0
+    while max_y>=0:
+      nameblock='Block_hor_'+self.name+str(indic)
+      self.addBlockDottedHoriz(nameblock,current_top) 
+      max_y=max_y-(y_max/float((y_range-1)))  #-1 because we don't want a dotted line on the X-axis
+      current_top+=(((height_global_div-height_header-height_axis_x)/float(nbr_line))-marge_top)/y_range #10px under the top of the line . float is important here! """ 
+      indic+=1
+    if self.soon!=[]:
+      for i in self.soon:
+        i.appendHorizontalDottedLine(marge_top,maximum_y,height_global_div,height_header,height_axis_x,nbr_line,y_range,y_max)
+    
+     
+  def appendActivityBlock(self,list_block):
+    indic=0
+    for data_block in list_block:
+      self.addBlock('ActivityBlock_'+self.name+'_'+str(indic),data_block)
+      indic+=1
+  
+
+  def createXAxis(self,x_axe,width_line,y_axis_width):
+    marge_left=y_axis_width
+    indic1=0
+    for i in x_axe[1]:
+      nameblock='block_'+self.name+str(indic1)
+      self.addBlockTextX(nameblock,marge_left,i)
+      indic1+=1  
+      marge_left+=width_line/float(len(x_axe[1]))
+      
+        
+  def addSoon(self,soon):
+    self.soon.append(soon)       
+
+    
+  def createLineChild(self,report_section,field,current_top,y_axis_width,width_line,space_line,height_global_div,height_header,height_axis_x,nbr_line,current_index,url): 
+
+    if len(report_section[current_index].getObject().objectValues())!=0:
+      paternity=1
+    else:
+      paternity=0   
+    soon=Line(title=str(report_section[current_index].getObject().getTitle()),name=self.name+'s'+str(current_index) ,begin=y_axis_width,width=width_line,height=(height_global_div-height_header-height_axis_x)/float(nbr_line),top=current_top,color='#ffffff',paternity=paternity,url=url) 
+
+    if (current_index+1)<=(len(report_section)-1): 
+     if report_section[current_index+1].getDepth() == 0:
+       current_top=current_top+((height_global_div-height_header-height_axis_x)/float(nbr_line))+space_line       
+     else:
+       current_top=current_top+((height_global_div-height_header-height_axis_x)/float(nbr_line))
+    self.addSoon(soon)                
+    return current_top 
+
+    
+    
+  def insertActivityBlock(self,line_content,object_start_method_id,object_stop_method_id,x_axe,field):
+    marge=0
+    method_start = getattr(line_content,object_start_method_id,None)
+    method_stop= getattr(line_content,object_stop_method_id,None)
+    block_begin = method_start()
+    list_block=[]
+    if method_stop!=None:
+      block_stop= method_stop()
+    else:
+      block_stop=None
+    
+    for i in x_axe[0]:
+      if isinstance(block_begin,DateTime):
+        comp_test1=block_begin.Date()==i    
+      else:
+        comp_test1=block_begin==i 
+      if comp_test1==True:
+
+        list_block.append([marge,(block_stop-block_begin)/(float(len(x_axe[0]))),0.75,{},0.25])   # 0.75(height) need to be defined
+      marge+=1/float(len(x_axe[0])) 
+    if list_block!=[]:
+      self.appendActivityBlock(list_block) 
+      
+    if self.soon!=[]:
+      script_x=getattr(line_content,field.get_value('data_method'),None)
+      soon_line=script_x()
+      indic=0
+      for s in soon_line:
+        self.soon[indic].insertActivityBlock(soon_line[indic],object_start_method_id,object_stop_method_id,x_axe,field)
+        indic+=1
+      
+        
+    
+#*************************************************   
+    
+# class block ***********************************     
+class Block:
+  def __init__(self,types,name,begin,width=0,height=0,text='',content={},marge_top=0):
+    self.types=types
+    self.name=name
+    self.begin=begin
+    self.width=width
+    self.height=height
+    self.text=text
+    self.content=content
+    self.marge_top=marge_top
+    # self.color=color need to be implemented in the future!
+    
+  def render(self,line_width,line_height,portal_url,line_begin,y_axis_width):
+    """used for inserting text in a block. one calculates how to organise the space.
+    one defines a width and height parameter (in pixel) which can be 
+    changed (depends on the size and the font used)
+    one fetches content which is a dictionnary like 
+    this {'center':'ezrzerezr','topright':'uihiuhiuh',
+          'topleft':'jnoinoin','botleft':'ioioioioi','botright':'ononono'}
+    """
+    string=''
+    font_height=10
+    font_width=6
+    info=''
+    
+    #checks if the block starts before the beginning of the line
+    if ((line_begin+self.begin*line_width) < line_begin): 
+      block_width=self.width+self.begin 
+    #checks if the block is too large for the end of the line. if it is the case, one cuts the block
+    elif ((self.width*line_width)+(line_begin+self.begin*line_width)>line_width+y_axis_width): 
+      block_width=self.width*line_width-((line_begin+self.begin*line_width+self.width*line_width)-(line_width+y_axis_width))
+      block_width=block_width/line_width
+    else:
+      block_width=self.width
+    
+    return self.buildInfoBlockBody(line_width,block_width,font_width,line_height) # NEED TO BE TESTED !!!
+    
+
+  def render_css(self,line_width,line_height,line,y_axis_width):
+    string=''
+    font_height=10
+    font_width=6
+    line_begin=line.begin
+
+    if ((line_begin+self.begin*line_width) < line_begin): #checks if the block starts before the beginning of the line
+      block_width=self.width+self.begin
+    elif ((self.width*line_width)+(line_begin+self.begin*line_width)>line_width+y_axis_width): #checks if the block is too large for the end of the line. if it is the case, one cuts the block
+      block_width=self.width*line_width-((line_begin+self.begin*line_width+self.width*line_width)-(line_width+y_axis_width))
+      block_width=block_width/line_width
+    else:
+      block_width=self.width
+    
+    return self.buildInfoBlockCss(font_height,line_height,block_width,line_width)   # NEED TO BE TESTED!!
+    
+    
+     #case with five informations
+     
+
+      #************************************************************************      
+  def addInfoCenter(self,info): #add info in the top left corner of a block    
+    self.content['center']=info  
+    
+  def addInfoTopLeft(self,info): #add info in the top left corner of a block    
+    self.content['topleft']=info
+  
+  def addInfoTopRight(self,info): #add info in the top right corner of a block    
+    self.content['topright']=info
+  
+  def addInfoBottomLeft(self,info): #add info in the bottom left corner of a block    
+    self.content['botleft']=info
+  
+  def addInfoBottomRight(self,info): #add info in the bottom right corner of a block    
+    self.content['botright']=info
+   
+    
+  # ****************************************     
+  def buildInfoBlockBody(self,line_width,block_width,font_width,line_height):
+    """ create the body of the html for displaying info inside a block"""
+    displayed1=['center','topright','topleft','botleft','botright']
+    displayed1=displayed1[0:len(self.content)]
+    string=''
+    for i in displayed1:
+      displayed[i]=0
+  
+    if len(self.content)==5:
+      test_height= font_height<=((self.height*line_height)/3)
+      test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/3))
+    if len(self.content)==4 or len(self.content)==3:
+      test_height= font_height<=((self.height*line_height)/2)
+      test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/2))
+    if len(self.content)==2:
+      test_height=font_height<=(self.height*line_height)
+      test_width= (len(self.content[i]*font_width)<=((block_width*line_width)/2))
+    if len(self.content)==1: 
+      test_height= font_height<=(self.height*line_height)
+      test_width= (len(self.content[i]*font_width)<=(block_width*line_width))   
+           
+    for i in self.content:
+       if test_height & test_width:
+         string+='<div id=\"'+self.name+i+'\">'+ self.content[i]
+         string+='</div>\n' 
+         displayed[i]=1
+  #******************checks if we need to add interrogation.png    
+    if ((self.width*line_width>=15) & (self.height*line_height>=15)): 
+      order=displayed1
+      for i in order:  
+        if displayed[i]==0:
+          info+=self.content[i]+'|' 
+      for i in order:
+        if displayed[i]==0:
+          string+='<div id=\"'+self.name+i+'\" title=\"'+info+'\"><img src=\"'+portal_url+'/images/question.png\" height=\"15\" width=\"15\"> '
+          string+='</div>\n'   
+          break
+       #******************  
+    return string     
+  #**************************************************
+
+    
+        
+#*******************************************    
+  def buildInfoBlockCss(self,font_height,line_height,block_width,line_width):
+    """use for creating css code when one needs to add info inside a block"""
+    displayed1=['center','topright','topleft','botleft','botright']
+    displayed1=displayed1[0:len(self.content)]
+    string=''
+    for i in displayed1:
+      displayed[i]=0
+     
+    if len(self.content)==5:
+      test_height= font_height<=((self.height*line_height)/3)
+      test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/3))
+    if len(self.content)==4 or len(self.content)==3:
+      test_height= font_height<=((self.height*line_height)/2)
+      test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/2))
+    if len(self.content)==2:
+      test_height=font_height<=(self.height*line_height)
+      test_width= (len(self.content[i]*font_width)<=((block_width*line_width)/2))
+    if len(self.content)==1: 
+      test_height= font_height<=(self.height*line_height)
+      test_width= (len(self.content[i]*font_width)<=(block_width*line_width))
+      
+    elif len(self.content)==0:
+      return ''
+    
+    matrix = {('center',5):{'left':2,'top':2},('center',4):{'left':0,'top':0},
+    ('center',3):{'left':2,'top':2},('center',2):{'left':0,'top':2},
+    ('center',1):{'left':2,'top':2},
+    ('topright',5):{'left':1,'top':0},('topright',4):{'left':1,'top':0},('topright',3):{'left':1,'top':0},('topright',2):{'left':1,'top':2},
+    ('topleft',5):{'left':0,'top':0},('topleft',4):{'left':1,'top':1},('topleft',3):{'left':0,'top':0},
+    ('botleft',5):{'left':0,'top':1},('topleft',4):{'left':0,'top':1},
+    ('botright',5):{'left':1,'top':1}
+    }
+    
+    matrix_picture = {('center',5):{'left':2,'top':2},('center',4):{'left':0,'top':0},
+    ('center',3):{'left':2,'top':2},('center',2):{'left':0,'top':2},('center',1):{'left':2,'top':2},
+    ('topright',5):{'left':1,'top':0},('topright',4):{'left':1,'top':0},('topright',3):{'left':1,'top':0},('topright',2):{'left':1,'top':2},
+    ('topleft',5):{'left':0,'top':0},('topleft',4):{'left':1,'top':1},('topleft',3):{'left':0,'top':0},
+    ('botleft',5):{'left':0,'top':1},('topleft',4):{'left':0,'top':1},
+    ('botright',5):{'left':1,'top':1}
+    }  
+    for i in self.content:         
+      for counter in range(1,5):
+        matrix_data = matrix[(i,counter)]
+        left = matrix_data['left']
+        top= matrix_data['top']
+        if left == 0:
+          margin_left=0
+        else:
+          margin_left = round(((block_width*line_width)/left)-(font_width*len(self.content[i]))/left)  
+        if top==0:
+          margin_top=0  
+        else:
+          margin_top = round(((self.height*line_height)/top)-(font_height/top))
+
+      if test_height & test_width:    
+        string+='#'+self.name+i+'{position:absolute;\nmargin-left:'+str(margin_left)+'px;\nmargin-top:'+str(margin_top)+'px;\n}\n'              
+        displayed[i]=1
+        line.addBlockInfo(self.name+i) 
+            
+        #******************checks if we need to add interrogation.png    
+    if ((block_width*line_width>=15) & (self.height*line_height>=15)): 
+      order=('center','topright','topleft','botleft','botright')
+      
+      for i in order:
+        for counter in range(1,5):
+          matrix_data= matrix [(i,counter)]
+          left = matrix_data['left']
+          top = matrix_data['top']
+          if left == 0:
+            margin_left=0
+          else:
+            margin_left=round(((block_width*line_width)/left)-(15/left))
+            
+          if top==0:
+            margin_top=0  
+          else:
+            margin_top=round(((self.height*line_height)/top)-(15/top))
+            margin_top = round(((self.height*line_height)/top)-(font_height/top))
+          if i=='center' & counter==3:
+            margin_left=round(((block_width*line_width)/left)-(font_width*len(self.content[i]))/left)  
+            margin_top=round(((self.height*line_height)/top)-(font_height/top))
+          if i=='center' & counter==2:  
+            margin_top=round(((self.height*line_height)/top)-(font_height/top))    
+          string+='#'+self.name+i+'{position:absolute;\nmargin-left:'+str(margin_left)+'px;\nmargin-top:'+str(margin_top)+'0px;\n}'  
+          line.addBlockInfo(self.name+i)
+    return string  
+ #####################################################
+ 
+ 
+            
+PlanningBoxWidgetInstance = PlanningBoxWidget()        
+ 
+          
+class PlanningBox(ZMIField):
+    meta_type = "PlanningBox"
+    widget = PlanningBoxWidgetInstance
+    validator = PlanningBoxValidatorInstance
+    security = ClassSecurityInfo()
+    security.declareProtected('Access contents information', 'get_value')
+    def get_value(self, id, **kw):
+      if id == 'default' and kw.get('render_format') in ('list', ):
+        return self.widget.render(self, self.generate_field_key() , None , kw.get('REQUEST'), render_format=kw.get('render_format'))
+      else:
+        return ZMIField.get_value(self, id, **kw)
+
+    def render_css(self, value=None, REQUEST=None):
+      return self.widget.render_css(self,'',value,REQUEST)
+                   
+