diff --git a/product/ERP5Form/PlanningBox.py b/product/ERP5Form/PlanningBox.py
index daaad7a2f16760108c82858f78deae6afb5e98ee..fefbbe2249a7b4d71930ecad9e03f23bed14cd3d 100755
--- a/product/ERP5Form/PlanningBox.py
+++ b/product/ERP5Form/PlanningBox.py
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
 #                    Jonathan Loriette <john@nexedi.com>
 #
 # WARNING: This program as such is intended to be used by professional
@@ -25,8 +25,6 @@
 # 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
@@ -35,36 +33,296 @@ from Products.Formulator.MethodField import BoundMethod
 from DateTime import DateTime
 from Products.Formulator import Widget, Validator
 from Products.Formulator.Errors import FormValidationError, ValidationError
-from SelectionTool import makeTreeList
+from SelectionTool import makeTreeList,TreeListLine
 from Selection import Selection, DomainSelection
 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):
-        list_value={}
-        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
-   
+  def validate(self, field, key, REQUEST):
+    """allows to check if one block is not outside of the planning"""
+    bmoved=REQUEST.get('block_moved')
+    form = field.aq_parent
+    height_global_div= field.get_value('height_global_div')    
+    width_line = field.get_value('width_line')
+    here = getattr(form, 'aq_parent', REQUEST)
+    space_line=field.get_value('space_line')
+    selection_name = field.get_value('selection_name')
+    sort = field.get_value('sort')
+    
+    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')
+    meta_types = field.get_value('meta_types')
+    list_method = field.get_value('list_method')
+    report_root_list = field.get_value('report_root_list')
+    portal_types = field.get_value('portal_types')
+    object_start_method_id = field.get_value('x_start_bloc')
+    object_stop_method_id= field.get_value('x_stop_bloc')
+    y_axis_width = field.get_value('y_axis_width')
+    script=getattr(here,field.get_value('x_axis_script_id'),None)
+    scriptY = getattr(here,field.get_value('max_y'),None)
+    x_range = field.get_value('x_range')
+    info_center = field.get_value('info_center')
+    info_topleft = field.get_value('info_topleft')        
+    info_topright = field.get_value('info_topright')
+    info_backleft = field.get_value('info_backleft')
+    info_backright = field.get_value('info_backright')
+    block_height= getattr(here,field.get_value('y_axis_method'),None)
+    portal_url = here.portal_url()
+    list_error=REQUEST.get('list_block_error')
+    old_delta2 = REQUEST.get('old_delta2')
+    lineb= REQUEST.get('line_begin')
+    if old_delta2!='None':
+      if old_delta2!='':
+        if old_delta2!={}:
+          old_delta2=convertStringToDict(old_delta2)
+    else:
+      old_delta2={}
+    
+    #first we rebuild the initial object structure with only line and activity block.
+    
+    # list_object is the variable that contains all the structure of the graphic.
+    # Basically, it a list a Line Object.
+    list_object=[]
+    selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST)
+    default_params = {}
+    if selection is None:
+      selection = Selection(params=default_params, default_sort_on = sort)
+    else:
+      selection.edit(default_sort_on = sort)
+      selection.edit(sort_on = sort)       
+    here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST)
+    current_top = height_header
+    #we check what is the current zoom in order to redefine height & width
+    current_zoom = selection.getZoom()
+    current_zoom= float(current_zoom)
+    if current_zoom<=1:
+      height_global_div = round(height_global_div * current_zoom)
+      width_line = round(width_line * current_zoom)
+      space_line = round(space_line * current_zoom)  
+    #we build line
+    (list_object,nbr_line,report_sections,blocks_object)=createLineObject(meta_types=meta_types,
+                                                            selection=selection,
+                                                            selection_name=selection_name,field=field,
+                                                            REQUEST=REQUEST,list_method=list_method,
+                                                            here=here,report_root_list=report_root_list,
+                                                            y_axis_width=y_axis_width,width_line=width_line,
+                                                            space_line=space_line,
+                                                            height_global_div=height_global_div,
+                                                            height_header=height_header,
+                                                            height_axis_x=height_axis_x,form=form,
+                                                            current_top=current_top,portal_types=portal_types)
+    # blocks_object is a dictionnary that contains all informations used for building blocks of each line
+ 
+    #we build x_occurence (used for the range in x-Axis 
+    x_occurence=[]
+    #report_sections contains treeListLine instance objects
+    for treelistobject in report_sections: 
+      method_start = getattr(treelistobject.getObject(),object_start_method_id,None)
+      method_stop= getattr(treelistobject.getObject(),object_stop_method_id,None)
+      if method_start!=None:
+        block_begin = method_start()
+      else:
+        block_begin = None
+      
+      if method_stop!=None:
+        block_stop= method_stop()
+      else:
+        block_stop=None
+      if block_begin != None: 
+       x_occurence.append([block_begin,block_stop])
+      #if method start is None it means that we construct the graphic with informations contained
+      #in blocks_object. 
+      if method_start == None and report_sections!={}:
+        for Ablock in blocks_object:
+          #object_content is the current object used for building a block.
+          #For instance if the context is a project, then object_content is an orderLine.
+          for object_content in blocks_object[Ablock]:
+            method_start = getattr(object_content,object_start_method_id,None)
+            method_stop= getattr(object_content,object_stop_method_id,None)
+              
+            if method_start!=None:
+              block_begin = method_start()
+            else:
+              block_begin = None
+            
+            if method_stop!=None:
+              block_stop= method_stop()
+            else:
+              block_stop=None
+              
+            if block_begin!=None:# and block_stop!=None:
+              x_occurence.append([block_begin,block_stop])
+          
+      params=selection.getParams()
+      start=params.get('list_start')
+      
+      x_axe=script(x_occurence,x_range,float(current_zoom),start)
+      y_max= 1
+      current_max = 1
+      #this part is used for determining the maximum through datas fetched via scriptY
+      #y_max is used when blocks have different height.
+      if scriptY != None:
+        for s in report_sections:
+          current_max=scriptY(s.getObject())
+          if current_max > y_max:
+            y_max = current_max
+      else:
+        y_max = 1
+      indic_line=0
+      while indic_line != len(report_sections):
+        # o is a Line object, for each line, we add its blocks via insertActivityBlock
+        for o in list_object:
+          if o.title == report_sections[indic_line].getObject().getTitle():
+            if list_object != [] and report_sections[indic_line].getDepth()==0:
+              o.insertActivityBlock(line_content=report_sections[indic_line].getObject(),
+                                    object_start_method_id=object_start_method_id,
+                                    object_stop_method_id=object_stop_method_id,
+                                    x_axe=x_axe,field=field,info_center=info_center,
+                                    info_topright=info_topright,info_topleft=info_topleft,
+                                    info_backleft=info_backleft,info_backright=info_backright,
+                                    list_error=list_error,old_delta=['None','None'],REQUEST=REQUEST,
+                                    blocks_object=blocks_object,width_line=width_line,
+                                    script_height_block=block_height,y_max=y_max)                                                      
+              break
+        indic_line+=1 
+    
+    #  the structure is now rebuilt
+    block_moved = [] 
+    bloc_and_line=[] # store the line and the coordinates of block moved
+    if bmoved != '':
+      block_moved=convertStringToList(bmoved)
+    else:
+      return ''
+    
+    # When a block is moved, we fetch its object Line and its corresponding object Blocks*
+    # via returnBlock 
+    for current_block in block_moved:
+      bloc_and_line=returnBlock(current_block,list_object,bloc_and_line)
+    
+    #At this point, we know which blocks have moved and the line they belong  
+    #IMPORTANT INFORMATION ABOUT RECORD:
+    #There is a problem with absolute and relative coordinates, that is why we do not
+    #directly use coordinates from bmoved, but only 'delta' which allows to find correct
+    #coordinates 
+    my_field = None
+    prev_delta='' #we store the current delta in a formated string
+    list_block_error = []
+    errors = []
+    error_result = {}
+    prev_deltaX=0
+    prev_deltaY=0
+    deltaX = 0 
+    deltaY = 0 
+    correct = 1 # correct = 1 if the block is correct otherwise correct = 0
+    new_object_planning = {} #structure returned
+    for mblock in bloc_and_line:
+      if old_delta2!=None:
+        # For each block that has moved, we add its former coordinates and its delta
+        if old_delta2.has_key(mblock[1].name):
+          prev_deltaX=float(old_delta2[mblock[1].name][0])
+          prev_deltaY=float(old_delta2[mblock[1].name][1])
+      deltaX =float(mblock[0][3]) - float(mblock[0][1])+prev_deltaX 
+      deltaY = float(mblock[0][4]) - float(mblock[0][2])+prev_deltaY
+      widthblock= float(mblock[0][5])
+      heightblock=float(mblock[0][6])
+      if mblock[1].url!='':
+        url = mblock[1].url
+      else:
+        url= mblock[2].url
+      # several test to know if a block is correct. If it is not, wee add it to list_block_error.
+      if mblock[1].begin <0:
+        deltaX = (mblock[1].begin)*mblock[2].width + float(mblock[0][3]) +prev_deltaX
+      # mblock[1] is a  block ; mblock[2] is a line
+      if (mblock[1].marge_top)*mblock[2].height+mblock[2].top+deltaY >mblock[2].top+mblock[2].height:  
+        correct = 0
+      if (mblock[1].marge_top)*mblock[2].height+heightblock+mblock[2].top+deltaY< mblock[2].top:
+        correct = 0
+      if (mblock[1].begin)*mblock[2].width+widthblock+mblock[2].begin+deltaX <mblock[2].begin:
+        correct = 0
+      if (mblock[1].begin)*mblock[2].width + deltaX+ mblock[2].begin> mblock[2].begin + mblock[2].width:
+        correct = 0
+      if correct == 0:
+        list_block_error.append(mblock)
+        err = ValidationError(StandardError,mblock[1])
+        errors.append(err)
+        if prev_delta!='':
+          prev_delta+='*'
+        prev_delta+=str(mblock[1].name)+','+str(deltaX)+','+str(deltaY)
+        # we store once again old_delta because we will need it when a block is moved again.     
+      else:
+        new_object_planning = convertDataToDate(mblock,x_axe,width_line, deltaX, 
+                                                deltaY, url, new_object_planning,lineb)  
+    REQUEST.set('list_block_error',list_block_error)
+    REQUEST.set('old_delta1',prev_delta)
+    if len(errors)>0:
+      raise FormValidationError(errors,{})
+    return new_object_planning
+
+def convertDataToDate(mblock,x_axe,width_line, deltaX, deltaY, object_url,
+                      new_object_planning, lineb):                 
+  """this is in this method that we calculate new startdate & stopdate in order 
+     to save them"""  
+  delta_axe = (DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+  #lineb is used to know where really starts the line due to problems with others html tags.
+  begin = (mblock[2].begin - float(mblock[0][3])+(float(lineb)-mblock[2].begin))*(-1)
+  length = float(mblock[0][5])
+  axe_begin = DateTime(x_axe[0][0])
+  coeff = float(delta_axe) / float(mblock[2].width)
+  delta_start = begin * coeff
+  delta_length = length * coeff
+  new_start = axe_begin + delta_start
+  new_stop=new_start + delta_length
+  new_object_planning[object_url]={'start_date':new_start,'stop_date':new_stop}
+  return new_object_planning    
+
+
 PlanningBoxValidatorInstance=PlanningBoxValidator()        
 
+
+def returnBlock(block_searched,planning_struct,block_and_line):
+  """return a specific structre containing the block object and its line 
+   thanks to its name"""
+  for line in planning_struct:
+    for block in line.content:
+      if block.name == block_searched[0]:
+        block_and_line.append([block_searched,block,line])   
+        break
+      else:
+        if line.son!=[]:
+          block_and_line = returnBlock(block_searched,line.son,block_and_line)
+  return block_and_line
+
+def convertStringToList(import_string):
+  """ convert a string from this type 'name,x,y,w,h-name,x,y,w,h...' to a list"""
+  list_moved= []
+  r_List = import_string.split('*')
+  for i in r_List:
+    current_block = i.split(',')
+    list_moved.append(current_block)
+  return list_moved
+
+def convertStringToDict(import_string):
+  """ convert a string from this type name,x1,x2,x,y,w,h*name,x1,x2,x,y,w,h
+      to list of dictionnaries where the key is the name""" 
+  dic={}
+  r_List=import_string.split('*')
+  for i in r_List:
+    current_block = i.split(',')
+    dic[current_block[0]]=[current_block[1],current_block[2]]
+  return dic    
+
+  
 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,portal_types):
+  """creates Line Object and stores it in list_object"""
   report_sections = []
   filtered_portal_types = map(lambda x: x[0], portal_types)
   if len(filtered_portal_types) == 0:
@@ -83,13 +341,10 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
   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'):
-    #add **************
     if list_method.method_name == 'objectValues':
       list_method = here.objectValues
       kw = copy(params)
@@ -117,7 +372,6 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
         list_method = getattr(here, list_method.method_name)
       except:
         pass
-    #add ****************
   elif list_method in (None, ''): # Use current selection
     list_method = None
   select_expression = ''
@@ -132,24 +386,26 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
     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)
+  report_tree_list = makeTreeList(here=here, form=form, root_dict=None,report_path=selection_report_path,
+                                  base_category=None,depth=0, 
+                                  unfolded_list=selection_report_current, selection_name=selection_name, 
+                                  report_depth=report_depth,
+                                  is_report_opened=is_report_opened, sort_on=selection.sort_on,
+                                  form_id=form.id)
   
   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():
+  index_line = 0
+  blocks_object= {}  
+  for object_tree_line in report_tree_list:      
+    selection.edit(report = object_tree_line.getSelectDomainDict())            
+    if object_tree_line.getIsPureSummary():
       original_select_expression = kw.get('select_expression')
       kw['select_expression'] = select_expression
       selection.edit( params = kw )
@@ -158,48 +414,67 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
       else:
         kw['select_expression'] = original_select_expression
     
-    if s.getIsPureSummary():
+    if object_tree_line.getIsPureSummary() and selection_report_path[0]=='parent':
       stat_result = {}
       index = 1
-      report_sections += [s]
+      report_sections += [object_tree_line]
       nbr_line+=1       
     else:
       # Prepare query
       selection.edit( params = kw )
       if list_method not in (None, ''):
-        selection.edit(exception_uid_list=s.getExceptionUidList())
+        selection.edit(exception_uid_list=object_tree_line.getExceptionUidList())
         object_list = selection(method = list_method, context=here, REQUEST=REQUEST)
       else:
         object_list = here.portal_selections.getSelectionValueList(selection_name,
                                                           context=here, REQUEST=REQUEST)
       
-    
-    selection.edit(report=None)
+      exception_uid_list = object_tree_line.getExceptionUidList()
+      if exception_uid_list is not None:
+      # Filter folders if this is a parent tree
+        new_object_list = []
+        for o in object_list:
+        #LOG('exception_uid_list', 0, '%s %s' % (o.getUid(), exception_uid_list))
+          if o.getUid() not in exception_uid_list:
+            new_object_list.append(o)
+                      
+        object_list = new_object_list
+      
+      current_list=[]
+      add = 1
+      #a test with 'add' variable because maketreelist return two times the 
+      #same object when it is open, don't know why...
+      for object in report_sections:
+        if getattr(object_tree_line.getObject(),'uid') == getattr(object.getObject(),'uid'):
+          add = 0
+          break  
+      if add == 1:       
+        report_sections += [object_tree_line] 
+        nbr_line+=1
+        for p in object_list:
+          current_list.append(p.getObject())
+        blocks_object[object_tree_line.getObject()]=current_list
+  selection.edit(report=None)
   index = 0
-
-  # we start to build our line object structure right here.
-  #for x in report_sections:
-  #  print x.getObject().getTitle()  
-  for l in report_sections:
+  #we start to build our line object structure right here.
+  index_report=0
+  for line_report 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()     
+    stat_context = line_report.getObject().asContext(**stat_result)
+    stat_context.domain_url = line_report.getObject().getRelativeUrl()
+    stat_context.absolute_url = lambda x: line_report.getObject().absolute_url()     
     url=getattr(stat_context,'domain_url','')
-    if l.getDepth() == 0:
-      paternity = 0
-      if len(l.getObject().objectValues())!=0:
-        paternity = 1
-    
+
+    if line_report.getDepth() == 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(),
+      line = Line(title=line_report.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:
@@ -217,20 +492,18 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
             height=((height_global_div-height_header-height_axis_x-
                    (((nbr_line-1))*space_line))/float(nbr_line))
             current_top=current_top+height 
-
     else:
       current_index = 0      
-      while l.getDepth() == report_sections[index-current_index].getDepth():
+      while line_report.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):
+        while depth != (line_report.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,
@@ -238,30 +511,29 @@ def createLineObject(meta_types,selection,selection_name,field,REQUEST,list_meth
                                                 ,height_axis_x,nbr_line,index,url)    
     index += 1
     indic_line+=1
-  return (list_object,nbr_line,report_sections)
+  return (list_object,nbr_line,report_sections,blocks_object)
 
-    
 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)        
+  """ create html code of children used by graphic library to know which block can be moved.
+      Refers to javascript library for more information"""
+  for line in current_line.son:
+    for block in line.content:
+      if block.types=='activity' or block.types=='activity_error':
+        graphic_call+='\"'+block.name+'\",'
+      elif block.types=='info':
+        graphic_call+='\"'+block.name+'\"+NO_DRAG,'   
+    if line.son!=[]: # case of a son which has sons...
+      graphic_call+=createGraphicCall(line,graphic_call)        
   return graphic_call
   
-  
 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',
+                     ['height_header', 'height_global_div','height_axis_x', 'width_line','space_line',
+                     'list_method','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_center',
-                     'info_topleft','info_topright','info_backleft','info_backright','security_index']
+                     'x_axis_script_id','x_start_bloc','x_stop_bloc','y_axis_method','max_y',
+                     'constraint_method','info_center','info_topleft','info_topright','info_backleft',
+                     'info_backright','security_index']
     
     default = fields.TextAreaField('default',
                                 title='Default',
@@ -305,15 +577,6 @@ class PlanningBoxWidget(Widget.Widget):
                                 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=(
@@ -348,7 +611,6 @@ class PlanningBoxWidget(Widget.Widget):
                                  default=[],
                                  required=0)
   
-                                 
     list_method = fields.MethodField('list_method',
                                  title='List Method',
                                  description=('The method to use to list'
@@ -356,14 +618,12 @@ class PlanningBoxWidget(Widget.Widget):
                                  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'),
@@ -381,7 +641,7 @@ class PlanningBoxWidget(Widget.Widget):
                                 title='number of range of Y-axis :',
                                 description=(
         "Number of Range of Y-axis, not required"),
-                                default=5,
+                                default=0,
                                 required=0) 
  
     x_range = fields.StringField('x_range',
@@ -397,7 +657,8 @@ class PlanningBoxWidget(Widget.Widget):
                                  required=0)	
 
     x_start_bloc = fields.StringField('x_start_bloc',
-                                 title='specific method which fetches the data for the beginning of a block:',
+                                 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',
@@ -412,12 +673,28 @@ class PlanningBoxWidget(Widget.Widget):
 
  
     y_axis_method = fields.StringField('y_axis_method',
+                                 title='specific method of data type for creating height of blocks',
+                                 description=('Method for building height of blocks'
+                                              'objects'),
+                                 default='',
+                                 required=0) 
+                                 
+
+    max_y  = fields.StringField('max_y',
                                  title='specific method of data type for creating Y-Axis',
                                  description=('Method for building Y-Axis'
                                               'objects'),
                                  default='',
-                                 required=0) 
+                                 required=0)
+
+  
   
+    constraint_method = fields.StringField('constraint_method',
+                                          title='name of constraint method between blocks',
+                                          description=('Constraint method between blocks'
+                                                      'objects'),
+                                          default='SET_DHTML',
+                                          required=1)
   
     info_center = fields.StringField('info_center',
                                  title='specific method of data called for inserting info in block center',
@@ -453,17 +730,17 @@ class PlanningBoxWidget(Widget.Widget):
                                  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"),
+                                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 #############################################
+        """In this method we build our structure object, then we return all the style sheet of each div"""
+        
+        # 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')
@@ -478,228 +755,357 @@ class PlanningBoxWidget(Widget.Widget):
         meta_types = field.get_value('meta_types')
         x_range=field.get_value('x_range')
         here = REQUEST['here']
-        
         title=field.get_value('title')
-        
         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')
+        scriptY = getattr(here,field.get_value('max_y'),None)
         script=getattr(here,field.get_value('x_axis_script_id'),None)
+        block_height= getattr(here,field.get_value('y_axis_method'),None)
+        constraint_method = field.get_value('constraint_method')
         #info inside a block
+        
         info_center = field.get_value('info_center')
         info_topleft = field.get_value('info_topleft')        
         info_topright = field.get_value('info_topright')
         info_backleft = field.get_value('info_backleft')
         info_backright = field.get_value('info_backright')
-        #*******
+
         object_start_method_id = field.get_value('x_start_bloc')
         object_stop_method_id= field.get_value('x_stop_bloc')
         form = field.aq_parent
         sort = field.get_value('sort')   
         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)
+                       #it is not directly coordinates but datas.                    
+        x_axe=[] # will contain what wee need to display in X-axis.
         yrange=[] # we store the value in Y-axis of each block 
         nbr=1
-        y_max=1      
+        blocks_object={}      
         current_top=height_header
-        total=[]
-        list_object=[] #in this list we store all the objects of type Line
+        line_list=[] #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 ######################
+        list_error=REQUEST.get('list_block_error')
+        old_delta=[REQUEST.get('old_delta1'),REQUEST.get('old_delta2')]
+        # END DATA DEFINITION                         
         
+        # we fetch fold/unfold datas 
         #here.portal_selections.setSelectionFor(selection_name, None)#uncoment to put selection to null
         selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST)
         default_params = {}
         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)
         else:
           selection.edit(default_sort_on = sort)
           selection.edit(sort_on = sort)       
         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,portal_types)
-        
-        # end build line ####################################################
+        # we check what is the current zoom in order to redefine height & width
+        current_zoom = selection.getZoom()
+        current_zoom= float(current_zoom)
+        if current_zoom<=1:
+          height_global_div = round(height_global_div * current_zoom)
+          width_line = round(width_line * current_zoom)
+          space_line = round(space_line * current_zoom)  
+        #we build lines 
+        (line_list,nbr_line,report_sections,blocks_object)=createLineObject(meta_types=meta_types,
+                                                                selection=selection,
+                                                                selection_name=selection_name,field=field,
+                                                                REQUEST=REQUEST,list_method=list_method,
+                                                                here=here,report_root_list=report_root_list,
+                                                                y_axis_width=y_axis_width,
+                                                                width_line=width_line,space_line=space_line,
+                                                                height_global_div=height_global_div,
+                                                                height_header=height_header,
+                                                                height_axis_x=height_axis_x,form=form,
+                                                                current_top=current_top,
+                                                                portal_types=portal_types)
+        #we build x_occurence (used for the range in x-Axis 
         
-         #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()
+        for tree_list_object in report_sections:
+          method_start = getattr(tree_list_object.getObject(),object_start_method_id,None)
+          method_stop= getattr(tree_list_object.getObject(),object_stop_method_id,None)
+          if method_start!=None:
+            block_begin = method_start()
+          else:
+            block_begin = None
+          
           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 
+          
+          if block_begin!=None:# and block_stop!=None:  
+            x_occurence.append([block_begin,block_stop])
+          
+          if method_start == None and report_sections!={}:
+            for Ablock in blocks_object:
+              for object_content in blocks_object[Ablock]:
+                method_start = getattr(object_content,object_start_method_id,None)
+                method_stop= getattr(object_content,object_stop_method_id,None)
+              
+                if method_start!=None:
+                  block_begin = method_start()
+                else:
+                  block_begin = None
+            
+                if method_stop!=None:
+                  block_stop= method_stop()
+                else:
+                  block_stop=None
+              
+                if block_begin!=None:# and block_stop!=None:
+                  x_occurence.append([block_begin,block_stop])
+          
+        params=selection.getParams()
+        start=params.get('list_start')
+        
+        x_axe=script(x_occurence,x_range,float(current_zoom),start)
+        #x_axe[0] is a list of chronological dates that wich represents the 
+        #the range of the graphic.for example: 
+        #x_axis=[['2005/11/04','2005/12/04' etc.],['april','may','june' etc.]
+        #,start_delimiter,delta]
+        # we add mobile block to the line object 
+        
+        y_max= 1
+        current_max = 1
+        if scriptY != None:
+          for s in report_sections:
+            current_max=scriptY(s.getObject())
+            if current_max > y_max:
+              y_max = current_max
+        else:
+          y_max = 1
+
+        indic_line=0
         while indic_line != len(report_sections):
-          for o in list_object:
-            if o.title == report_sections[indic_line].getObject().getTitle():
-              if list_object != [] and report_sections[indic_line].getDepth()==0:
-                o.insertActivityBlock(report_sections[indic_line].getObject(),object_start_method_id,
-                                      object_stop_method_id,x_axe,field,info_center,info_topright,info_topleft,
-                                      info_backleft,info_backright)                                                      
+          for object_line in line_list:
+            if object_line.title == report_sections[indic_line].getObject().getTitle():
+              if line_list != [] and report_sections[indic_line].getDepth()==0:
+                object_line.insertActivityBlock(line_content=report_sections[indic_line].getObject(),
+                                      object_start_method_id=object_start_method_id,
+                                      object_stop_method_id=object_stop_method_id,
+                                      x_axe=x_axe,field=field,info_center=info_center,
+                                      info_topright=info_topright,info_topleft=info_topleft,
+                                      info_backleft=info_backleft,info_backright=info_backright,
+                                      list_error=list_error,old_delta=old_delta,REQUEST=REQUEST,
+                                      blocks_object=blocks_object,width_line=width_line,
+                                      script_height_block=block_height,y_max=y_max)                                                      
                 break
           indic_line+=1
-        # #############################################################
-        # at this point list_object contains our tree of datas. Then we add others objects for the graphic.
+        # At this point line_list contains our tree of datas. Then we
+        # add others labels, indicators etc. 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 vertical dotted line
+        if x_axe != []:        
+          marge_left=y_axis_width+width_line/float(len(x_axe[1]))
+          for i in line_list:
+            i.appendVerticalDottedLine(x_axe,width_line,marge_left)
 
-            
-        #one constructs the maximum horizontal dotted line 10px under the top of the line***************
+        #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:  
+        marge_top=10
+        if y_range!=0:
+          for i in line_list:  
             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 ********************************************************
-   
+                                         height_axis_x,nbr_line,y_range,y_max)
+        #end construct of horizontal dotted line 
 
-        # we construct y-axis   ******************************
+        # we construct y-axis
         way=[]    
-        y=[]
+        y=[] #we store here the objects for creating y-axis 
         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)  
-          
-          height=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line))+space_line
-          current_top=y[len(y)-1].top+height
+        
+        for i in line_list:
+          current_top=i.buildYtype(way=way,y=y,level=level,y_axis_width=y_axis_width,
+                                   height_global_div=height_global_div,height_header=height_header,
+                                   height_axis_x=height_axis_x,nbr_line=nbr_line,current_top=current_top,
+                                   space_line=space_line,y_max=y_max,y_range=y_range,
+                                   y_unity=y_unity,selection_name=selection_name,form=form)  
+          height=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/\
+                 float(nbr_line))+space_line
+          current_top=y[-1].top+height
           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 	 
+        line_list=y+line_list #we need to add the y-axis block at the beginning of our structure
+                                  #otherwise the display is not correct;don't know why...
 
-        
-        #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)
-       #***************************
-        x_subdivision=width_line/float(len(x_axe[1]))
-        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)
-        SESSION.set('title',title)
-        for i in list_object:
+        #build X axis 
+        line_list.append(Line('','axis_x',y_axis_width,width_line,height_axis_x,\
+                                current_top-space_line)) 
+        line_list[-1].createXAxis(x_axe,width_line,y_axis_width)
+        if x_axe!=[]:
+          x_subdivision=width_line/float(len(x_axe[1]))
+        else:
+          x_subdivision = 0
+        REQUEST.set('line_list',line_list)  
+        REQUEST.set('width_line',width_line) 
+        REQUEST.set('height_global', height_global_div)
+        REQUEST.set('y_axis_width', y_axis_width)
+        REQUEST.set('report_root_list',report_root_list)
+        REQUEST.set('selection_name',selection_name)
+        REQUEST.set('title',title)
+        REQUEST.set('x_axe',x_axe)
+        REQUEST.set('start',start)
+        REQUEST.set('delta1',old_delta[0])
+        REQUEST.set('delta2',old_delta[1])
+        REQUEST.set('constraint_method',constraint_method)
+        for i in line_list:
           giant_string+=i.render_css(y_axis_width,security_index,x_subdivision)   
         return giant_string
-      
-        
-                
-       
+    
     def render(self,field, key, value, REQUEST):
+        """ this method return a string called 'giant_string' wich contains the planningbox html
+            of the web page""" 
         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')
-        title=SESSION.get('title')
-        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:px\">\n'""" 
+        title = REQUEST.get('title')
+        line_list = REQUEST.get('line_list')
+        x_axe = REQUEST.get('x_axe')  
+        width_line=REQUEST.get('width_line')
+        start_page=REQUEST.get('list_start')
+        height_global_div=REQUEST.get('height_global')
+        y_axis_width=REQUEST.get('y_axis_width')
+        report_root_list=REQUEST.get('report_root_list')
+        selection_name=REQUEST.get('selection_name')
+        start_page=REQUEST.get('start')
+        constraint_method=REQUEST.get('constraint_method')
+        #the following javascript function allows to know where is exactly situated 
+        #the beginning of lines in absolute coordinates since we have problems due to 
+        #others tags (form,tr,table...) which are declared previously in the html.    
         
-        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:-2px;\
-                      border-style:solid;border-color:#000000;border-width:1px;margin-top:-1px\">\n'
+        giant_string="""<script type="text/javascript">
+        function setLineBegin()
+        {
+        document.forms["main_form"]["line_begin"].value = document.getElementById("fra0").offsetLeft;
+        }
+        window.onmousemove = setLineBegin;
+        </script>"""
         
-        #header of the graphic******************************************
+        # we record current delta in delta1, and we record old_delta in delta2
+        odelta=[REQUEST.get('delta1'),REQUEST.get('delta2')]
+        selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST)
+        giant_string+='<input type=\"hidden\" name=\"list_selection_name\" value='+selection_name+' />\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:0px;\
                        border-style:solid;border-color:#000000;border-width:1px;margin-top:1px\">\
                        <table><tr><td><h3><u>'+title+'</h3></u></td><td>'
-        ##########################report tree
-        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></td></tr></table></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('
+        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></td>\n""" % (here.getUrl(),report_tree_options)
+        giant_string += report_popup
         
-        for i in range(0,len(total)):
+        #now we declare zoom widget 
+        current_zoom=selection.getZoom()
+        zoom=(0.25,0.5,0.75,1,2,4,8,10)
+        zoom_select= """<td>
+              <select name="zoom" onChange="submitAction(this.form,'"""
+        zoom_select+=here.getUrl()+ '/portal_selections/setZoom\')">'
+        for z in zoom:
+          if z == float(current_zoom):
+            zoom_select+='<option selected value=\"'+str(z)+'\">x'+str(z)+'</option>\n'
+          else:
+            zoom_select+='<option value=\"'+str(z)+'\">x'+str(z)+'</option>\n'
+        giant_string += zoom_select
+        
+        
+        #now the page number widget 
+        pages='</select></td><td><select name="list_start" title=Change  \
+        onChange="submitAction(this.form,\''+here.getUrl()+'/portal_selections/setPage\')">'
+        selected=''
+        date_planning=''
+        if x_axe!=[]:
+          x_planning=x_axe[2]
+          delta=x_axe[3]
+          if isinstance(x_planning, DateTime):
+            date_planning = x_planning
+            for p in range(1,float(current_zoom)+1):
+              if x_planning == start_page :
+                selected= 'selected '
+              else:
+                selected= '' 
+              pages+='<option '+selected+'value=\"'+str(date_planning.Date())+'\">'+str(p)+' of '\
+                     +str(current_zoom)+'</option>\n'
+              date_planning+=delta
+              x_planning=date_planning.Date()
+          else:
+            for p in range(1,float(current_zoom)+1):
+              axe_index = 0
+              while x_planning != x_axe[0][axe_index]:
+                axe_index+=1 
+              
+              if x_planning == start_page :
+                selected= 'selected '
+              else:
+                selected= '' 
+              pages+='<option '+selected+'value=\"'+str(x_axe[0][axe_index])+'\">'+str(p)+' of '\
+                     +str(current_zoom)+'</option>\n'
+              axe_index = axe_index + delta       
+              current_item = x_axe[0][axe_index]
+        else:
+          x_planning=[]
+          delta=0
+  
+        pages+='</select></td></tr></table></div>\n'        
+        giant_string += pages 
+        #just because setPage wants it
+        giant_string += '<input type=\"hidden\" name=\"listbox_uid:list\">\n'
+        #we change old_delta2 to  old_delta1
+        giant_string += '<input type=\"hidden\" name=\"old_delta1\" value=\"'+str(odelta[0])+'\">\n'
+        giant_string += '<input type=\"hidden\" name=\"old_delta2\" value=\"'+str(odelta[0])+'\">\n' 
+        giant_string+= '<input type=\"hidden\" name=\"block_moved\">\n'
+        giant_string+= '<input type=\"hidden\" name=\"line_begin\">\n'
+
+        for i in range(0,len(line_list)):
+          giant_string+=line_list[i].render(portal_url,y_axis_width)    
+
+        #here is the declaration of four divs which are used for redimensionning
+        giant_string+='<div id=\"top\" style=\"position:absolute;width:5px;height:5px;\
+                        background:#a45d10\"></div>\n'
+        giant_string+='<div id=\"right\" style=\"position:absolute;width:5px;height:5px;\
+                        background:#a45d10"></div>\n'
+        giant_string+='<div id=\"bottom\" style=\"position:absolute;width:5px;height:5px\
+                       ;background:#a45d10\"></div>\n'
+        giant_string+='<div id=\"left\" style=\"position:absolute;width:5px;height:5px;\
+                       background:#a45d10\"></div>\n'
+        giant_string+='<script type=\"text/javascript\">\n'+ constraint_method + '('
+
+        for i in range(0,len(line_list)):
           graphic_call=''
-          for j in total[i].content:
-            if j.types=='activity':
+          for j in line_list[i].content:
+            if j.types=='activity' or j.types=='activity_error':
               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> '
+          current_object=line_list[i]
+          if current_object.son!=[]:  
+           giant_string+=createGraphicCall(current_object,graphic_call)     
+        giant_string+='\"top\"+CURSOR_N_RESIZE+VERTICAL, \"right\"+CURSOR_E_RESIZE+HORIZONTAL,\
+                       \"bottom\"+CURSOR_S_RESIZE+VERTICAL,\
+                       \"left\"+CURSOR_W_RESIZE+HORIZONTAL);\n'
+        giant_string+='</script> </div> \n '
         return giant_string  
-#***************************************************          
-          
-
 
-# class line **************************************
+# 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 = []
+  """objects which represent a line directly in a planningbox"""
+  def __init__(self,title='',name='',begin=0,width=0,height=0,top=0,color='',son=None,y_type='none',
+               paternity=0,url=''):  
+    """used for building a Line object"""
+    if son is None:
+     son = []
     self.title=title
     self.name=name
     self.begin=begin
@@ -708,27 +1114,28 @@ class Line:
     self.top=top
     self.content=[]
     self.color=color
-    self.soon=soon
+    self.son=son
     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 """
+    """ creates "pure" html code of the line, its Block, its son """
     html_render='<div id=\"'+self.name+'\"></div>\n'
     for j in self.content:
-      if j.types=='activity':
-        #checks if the block is too large for the end of the line if it is the case, one cuts the block
-        if ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width): 
-          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
+      if j.types=='activity' or j.types=='activity_error':
+        #checks if the block starts before the beginning of the line               
+        if ((self.begin+j.begin*self.width) < self.begin): 
           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()
+                       + 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()
+        #checks if the block is too large for the end of the line if it is the case, one cuts the block
+        elif ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width): 
+          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))+') \">'
         else:
           html_render+='<div id=\"'+j.name+'\" ondblclick=\"showGrips()\">'      
         # we add info Block inside the div thanks to the render method of the Block class
@@ -736,142 +1143,162 @@ class Line:
         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:
+    if self.son!=[]:
+      for i in self.son:
         html_render+=i.render(portal_url,y_axis_width)      
     return html_render    
     
     
   def render_css(self,y_axis_width,security_index,x_subdivision):
-    css_render='#'+self.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\nborder-width:1px;\n'
+    """creates style sheet of each div which represents a Line instance """
+    css_render='#'+self.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\
+                               \nborder-width:1px;\n'
+    data={}
     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':
+    elif self.y_type=='son1':
       css_render+='border-top-width:0px;\nborder-bottom-width:0px;\n'    
-    elif self.y_type=='soon2':
+    elif self.y_type=='son2':
       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'
+      if j.types=='activity' or j.types=='activity_error':
+        if j.types=='activity':
+          css_render+='#'+j.name+'{position:absolute;\nbackground:#bdd2e7;\nborder-style:solid;\
+                      \nborder-color:#53676e;\nborder-width:1px;\n'
+        if j.types=='activity_error':
+          css_render+='#'+j.name+'{position:absolute;\nbackground:#bdd2e7;\nborder-style:solid;\
+                      \nborder-color:#ff0000;\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
-        
-        if ((self.begin+j.begin*self.width) < self.begin): 
+        if ((self.begin+j.begin*self.width) < self.begin) and j.types!='activity_error': 
         #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' 
         #checks if the block is too large for the end of the line. if it is the case, one cuts the block  
-        elif ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width): 
-          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'
-
+        elif ((j.width*self.width)+(self.begin+j.begin*self.width)>self.width+y_axis_width) and \
+               j.types!='activity_error': 
+          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,self,y_axis_width)  # we add info Block inside the div       
+        css_render+='margin-top:'+str(self.top+10+j.marge_top*(self.height-10))+'px;}\n'
+        # we add info Block inside the div  
+        css_render+=j.render_css(self.width,self.height,self,y_axis_width)       
         
       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'
+        data={'border-style:':'solid;','border-color:':'#53676e;','border-width:':'1px;',
+              'margin-left:':str(j.begin)+'px;',
+              'margin-top:':str(round(1+self.top+self.height/2))+'px;'}
         
       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'
+        data={'border-style:':'solid;','border-color:':'#53676e;','border-width:':'0px;',  
+              'margin-left:':str(self.width/4)+'px;',
+              'margin-top:':str(round(1+self.top+self.height/2))+'px;'}
 
 
       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' 
+        data={'border-style:':'dotted;','border-color':'#53676e;',
+              'margin-left:':str(j.begin)+'px;','margin-top:':str(1+round(self.top))+'px;',
+              'height:':str(self.height)+'px;',
+              'border-left-width:':'1px;','border-right-width:':'0px;','border-top-width:':'0px;',    
+              'border-bottom-width:':'0px;'}
 
       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'
+        data={'border-style:':'dotted;','border-color:':'#53676e;',
+               'margin-left:':str(self.begin)+'px;','margin-top:':str(self.top+j.marge_top)+'px;',
+               'border-left-width:':'0px;','border-right-width:':'0px;',
+               'border-top-width:':'1px;','border-bottom-width:':'0px;',
+               'width:':str(self.width)+'px;'}
 
       elif j.types=='y_coord':
-        css_render+='#'+j.name+'{position:absolute;\nborder-style:solid;\nborder-color:#53676e;\
-                    \nfont-size:9px;\nborder-width:0px;\n'
-        #x5 because this is the appropriate width for our font (9px), maybee need to be parameter            
-        css_render+='margin-left:'+str(self.width-(len(j.text)*5))+'px;\n' 
-        css_render+='margin-top:'+str(self.top+j.marge_top)+'px;}\n'
-
+        data={'border-style:':'solid;','border-color:':'#53676e;','border-width:':'0px;',
+               'margin-left:':str(self.width-(len(j.text)*5))+'px;',
+               'margin-top:':str(self.top+j.marge_top)+'px;',
+               'height:':'','border-left-width:':'1px;','border-right-width:':'0px;',
+               'border-top-width:':'0px;','border-bottom-width':'0px;','font-size:':'9px;'}
+            
       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'
-
+        data={'border-style:':'solid;','border-color:':'#53676e;',
+              'margin-left:':str((self.width/4)+j.begin)+'px;',
+              'margin-top:':str(round(self.top)-self.height/2+13)+'px;',
+              'height:':str(j.height)+'px;','border-left-width:':'1px;',
+              'border-right-width:':'0px;','border-top-width:':'0px;', 
+              'border-bottom-width:':'0px;'}
+                       
       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(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,x_subdivision);
+        data={'border-style:':'solid;','border-color:':'#53676e;',
+              'margin-left:':str((self.width/4)+j.begin)+'px;',
+              'margin-top:':str(round(1+self.top+self.height/2))+'px;',
+              'height:':'1px;','border-left-width:':'0px;','border-right-width:':'0px;',
+              'border-top-width:':'1px;','border-bottom-width:':'0px;','width:':'16px;','height:':'1px;',
+             }      
+
+      if j.types!='activity':
+        if j.types!='activity_error':
+          if j.types!='info':
+            css_render+='#'+j.name+'{position:absolute;\n'
+            for key in data:
+              css_render+=key + data[key] + '\n'
+            css_render+='}\n'  
 
+    if self.son!=[]:
+      for i in self.son:
+        css_render+=i.render_css(y_axis_width,security_index,x_subdivision);
     return css_render      
 
+  def addBlock(self,name,block,error=0):
+    """just create and add a block inside 'content' attribut of a Line instance""" 
+    type_block=''
+    if error == 0:
+      type_block='activity'
+    else:
+      type_block='activity_error'
+    self.content.append(Block(type_block,name=name,begin=block[0],width=block[1],height=block[2],text='',
+                              content=block[3],marge_top=block[4],url=block[5]))
     
-
-  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):
+    """add a block info inside an activity block"""
     self.content.append(Block('info',name,0,0,0,''))
     
   def addBlockTextY(self,name,text):
+    """ add a text  block in y-axis"""
     self.content.append(Block('text_y',name,0,0,0,text))  
   
   def addBlockCoordY(self,name,text,marge_top):
+    """ add a text block in y-axis (coordinates) """
     self.content.append(Block('y_coord',name,0,0,0,text,{},marge_top))  
     
   def addBlockTextX(self,name,begin,text):
+    """ add a text block in x-axis"""
     self.content.append(Block('text_x',name,begin,0,0,text))    
     
   def addBlockDottedVert(self,name,begin):
+    """ add a vertical dotted line"""
     self.content.append(Block('vertical_dotted',name,begin,0,0,''))  
     
   def addBlockDottedHoriz(self,name,marge_top):
+    """append a dotted horizontal block"""
     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)) 
+    """append a vertical block(line)""" 
+    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))    
+    """append a horizontal  block (line)""" 
+    self.content.append(Block('horizontal',name,marge_left,0,height,'',{},marge_top))    
          
-
- 
-      
-    
   def appendVerticalDottedLine(self,x_axe,width_line,marge_left):
+    """append a vertical dotted  block"""
     current_marge=marge_left
     indic=0
     for j in x_axe[1]:
@@ -879,104 +1306,117 @@ class Line:
       self.addBlockDottedVert(nameblock,current_marge)
       current_marge+=width_line/float(len(x_axe[1]))   
       indic+=1
-      
-    if self.soon!=[]:
-      for i in self.soon:
+    if self.son!=[]:
+      for i in self.son:
         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): 
+  def buildYtype(self,way=[],y=[],level=0,y_axis_width=0,height_global_div=0,height_header=0,
+                 height_axis_x=0,nbr_line=0,current_top=0,space_line=0,y_max=0,y_range=0,
+                 y_unity=0,selection_name='',form=0): 
     """ 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' """
+       'way' is a list whichs allows to determinate if the current block is a type 'son1' or 'son2'.
+        y parameter is a list which contains all the objects for creating y-axis.  
+
+    """
     report_url=self.url
     if level==0:
       name='axis'+str(self.name)
-      if self.soon!=[]:
+      if self.son!=[]:
         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'))
+        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>')
+        if self.son!=[]:
+          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>')
-          
-
+          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)
+        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)
+        y[-1].createIndicators(y_unity,y_range,y_max,height_global_div,height_header,height_axis_x,nbr_line)
       
-      if self.soon!=[]:
+      if self.son!=[]:
         level+=1
-        for j in range(0,len(self.soon)):
-          if j==(len(self.soon)-1):
+        for j in range(0,len(self.son)):
+          if j==(len(self.son)-1):
             way.append(1)
           else:
             way.append(0)
-          current_top+=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/float(nbr_line))  
+          current_top+=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/
+                       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]
+          current_top=self.son[j].buildYtype(way=way,y=y,level=level,y_axis_width=y_axis_width,
+                                             height_global_div=height_global_div,
+                                             height_header=height_header,
+                                             height_axis_x= height_axis_x,nbr_line=nbr_line,
+                                             current_top=current_top,space_line=space_line,
+                                             y_max=y_max,y_range=y_range,
+                                             y_unity=y_unity,selection_name=selection_name,form=form)
+          del way[-1]
   
     else:
-      if self.soon!=[]:
+      if self.son!=[]:
         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'))
+                      ,current_top,'',[],'son1'))
 
         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>')
+          if self.son!=[]:
+            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>') 
+            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)
+          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-((nbr_line-1)*space_line))/float(nbr_line),3*level*5-18) 
+        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-((nbr_line-1)*space_line))\
+                                    /float(nbr_line),3*level*5-18) 
                                      #5 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-((nbr_line-1)*space_line))/float(nbr_line),3*level*5-18) 
-        
+        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-((nbr_line-1)*space_line))\
+                                    /float(nbr_line),3*level*5-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)
+          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):
+        for j in range(0,len(self.son)):
+          current_top+=((height_global_div-height_header-height_axis_x-((nbr_line-1)*space_line))/\
+                       float(nbr_line))
+          if j==(len(self.son)-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]
-  
+          current_top=self.son[j].buildYtype(way=way,y=y,level=level,y_axis_width=y_axis_width,
+                                             height_global_div=height_global_div,
+                                             height_header=height_header,height_axis_x=height_axis_x,
+                                             nbr_line=nbr_line,current_top=current_top,
+                                             space_line=space_line,y_max=y_max,y_range=y_range,
+                                             y_unity=y_unity,selection_name=selection_name,form=form)
+          del way[-1]
       else:
         name=str(self.name)
         test='true'
@@ -985,34 +1425,44 @@ class Line:
           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'))
+          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,'',[],'son2'))
         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'))
+          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,'',[],'son1'))
           
-
         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>')
+          if self.son!=[]:
+            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>')
+            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)  
+          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*5-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*5-18) 
-        
+        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*5-18)  
+        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*5-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)
+          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
+  def createIndicators(self,y_unity,y_range,y_max,height_global_div,height_header,\
+                       height_axis_x,nbr_line):
+    """creates a blocks used for y-axis coordinates"""
+    
     maximum_y=y_max
     marge_top=0
     indic=0
@@ -1023,68 +1473,107 @@ class Line:
       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): 
+
+  def appendHorizontalDottedLine(self,marge_top,maximum_y,height_global_div,height_header,
+                                 height_axis_x,nbr_line,y_range,y_max): 
+    """creates a horizontal dotted line """
     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)
-    
+    if y_range !=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
+        #10px under the top of the line . float is important here!
+        current_top+=(((height_global_div-height_header-height_axis_x)/float(nbr_line))-marge_top)/y_range
+        indic+=1
+      if self.son!=[]:
+        for i in self.son:
+          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):
+  def appendActivityBlock(self,list_block,list_error,old_delta,REQUEST):
+    """create an activity block"""
     indic=0
+    name_block=''
+    prev_deltaX=0
+    prev_deltaY=0
+    old_delta2=old_delta[1]
+    if old_delta2!='None' and old_delta2!=None:
+      if old_delta2!='':
+        if old_delta2!={}:
+          old_delta2=convertStringToDict(old_delta2)
+    else:
+      old_delta2={}  
+    
     for data_block in list_block:
-      self.addBlock('ActivityBlock_'+self.name+'_'+str(indic),data_block)
+      name_block='ActivityBlock_'+self.name+'_'+str(indic)
+      if list_error != None: 
+        for blockerror in list_error: #we are about to build block with red border
+          if blockerror[0][0] == name_block:
+            if old_delta2.has_key(name_block):
+              prev_deltaX=float(old_delta2[name_block][0])
+              prev_deltaY=float(old_delta2[name_block][1])
+            deltaX =float(blockerror[0][3]) - float(blockerror[0][1])+prev_deltaX 
+            deltaY = float(blockerror[0][4]) - float(blockerror[0][2])+prev_deltaY
+            #data_block_error is [begin,width,top,info,height]
+            begin=(blockerror[1].begin*blockerror[2].width+deltaX)/blockerror[2].width
+            width=float(blockerror[0][5])/blockerror[2].width
+            top=((blockerror[1].marge_top)*(blockerror[2].height-10)+deltaY)/(blockerror[2].height-10)
+            height=float(blockerror[0][6])/(blockerror[2].height-10)
+            data_block_error= [begin,width,height,data_block[3],top,blockerror[1].url]
+            self.addBlock(name_block,data_block_error,1)  
+          else:
+            self.addBlock(name_block,data_block)
+      else:
+        self.addBlock(name_block,data_block)  
       indic+=1
-  
-
+    
   def createXAxis(self,x_axe,width_line,y_axis_width):
+    """creates x-axis """
     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]))
+    if x_axe!=[]:
+      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): 
+  def addSon(self,son):
+    """add a child Line to a Line """
+    self.son.append(son)       
 
+  def createLineChild(self,report_section=None,field='',current_top=0,y_axis_width=0,
+                      width_line=0,space_line=0,height_global_div=0,height_header=0,
+                      height_axis_x=0,nbr_line=0,current_index=0,url=''): 
+    """ create the Line object which is the son of an other Line Object"""
     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-((nbr_line-1)*space_line))/float(nbr_line),top=current_top,color='#ffffff',paternity=paternity,url=url) 
-
+    son=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-((nbr_line-1)*space_line))\
+              /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-((nbr_line-1)*space_line))/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))
-    self.addSoon(soon)                
+       current_top=current_top+((height_global_div-height_header-height_axis_x-
+                   ((nbr_line-1)*space_line))/float(nbr_line))
+    self.addSon(son)                
     return current_top 
 
-    
-    
-  def insertActivityBlock(self,line_content,object_start_method_id,object_stop_method_id,
-                          x_axe,field,info_center,info_topright,info_topleft,info_backleft,
-                          info_backright):
+  def insertActivityBlock(self,line_content=None,object_start_method_id=None,object_stop_method_id=None,
+                          x_axe=[],field='',info_center='',info_topright='',info_topleft='',
+                          info_backleft='',info_backright='',list_error='',old_delta='',REQUEST=None,
+                          blocks_object={},width_line=0,script_height_block=None,y_max = 1):
     """allows to create the mobile block objects"""
     #first we check if the block has information
-    
     center= getattr(line_content,info_center,None) 
     topright = getattr(line_content,info_topright,None)
     topleft = getattr(line_content,info_topleft,None)
@@ -1095,56 +1584,178 @@ class Line:
     if topright!=None: info['topright']=str(topright())
     if topleft!=None: info['topleft']=str(topleft())
     if backleft!=None: info['botleft']=str(backleft())
-    if backright!=None: info['botright']=str(backright()) 
+    if backright!=None: info['backright']=str(backright()) 
     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()
+    wrong_left=0 
+    wrong_right=0
     list_block=[]
-    if method_stop!=None:
-      block_stop= method_stop()
+    if method_start==None and blocks_object!={}:
+      for Ablock in blocks_object:
+        #object_content is the current object used for building a block.
+        #For instance if the context is a project, then object_content is an orderLine.
+        for object_content in blocks_object[Ablock]:
+          if self.title == Ablock.getObject().getTitle(): 
+            method_start = getattr(object_content,object_start_method_id,None)  
+            method_stop= getattr(object_content,object_stop_method_id,None)     
+    
+            if method_start != None:
+              block_begin = method_start()
+            else:
+              block_begin = None
+      
+            if method_stop!=None:
+              block_stop= method_stop()
+            else:
+              block_stop=None
+            if isinstance(block_begin,DateTime):    
+                if round(block_begin-DateTime(x_axe[0][0]))>0:
+                  block_left=float(round(block_begin-DateTime(x_axe[0][0])))/round(
+                             DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+                elif round(block_begin-DateTime(x_axe[0][0]))==0:
+                  block_left=0
+                else:
+                  block_left=float(round(block_begin-DateTime(x_axe[0][0])))/round(
+                         DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+
+                if block_stop-DateTime(x_axe[0][0])<=0:
+                  wrong_left = 1  #means that the block is outside of x-axis range
+        
+                if block_begin-DateTime(x_axe[0][-1])>=0:            
+                  wrong_right = 1 #the same
+      
+                block_right=float(round(block_stop-DateTime(x_axe[0][0])))/round(
+                              DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+                
+                center= getattr(object_content,info_center,None) 
+                topright = getattr(object_content,info_topright,None)
+                topleft = getattr(object_content,info_topleft,None)
+                backleft= getattr(object_content,info_backleft,None)
+                backright= getattr(object_content,info_backright,None)
+                info={}
+                if center!=None: info['center']=str(center())
+                if topright!=None: info['topright']=str(topright())
+                if topleft!=None: info['topleft']=str(topleft())
+                if backleft!=None: info['botleft']=str(backleft())
+                if backright!=None: ignfo['botright']=str(backright())
+                url = getattr(object_content,'domain_url','')
+                url = object_content.getUrl()
+                if script_height_block == None or y_max==1:
+                  height = 0.75
+                else:
+                  height = float(script_height_block(object_content))/y_max
+                if wrong_left!=1 and wrong_right!=1: # if outside we do not display
+                  list_block.append([block_left,block_right-block_left,height,info,1-height,url])
+            else:
+              if block_begin !=None:
+                for i in x_axe[0]:
+                  if block_begin==i:
+                    center= getattr(object_content,info_center,None) 
+                    topright = getattr(object_content,info_topright,None)
+                    topleft = getattr(object_content,info_topleft,None)
+                    backleft= getattr(object_content,info_backleft,None)
+                    backright= getattr(object_content,info_backright,None)
+                    info={}
+                    if center!=None: info['center']=str(center())
+                    if topright!=None: info['topright']=str(topright())
+                    if topleft!=None: info['topleft']=str(topleft())
+                    if backleft!=None: info['botleft']=str(backleft())
+                    if backright!=None: ignfo['botright']=str(backright())
+                    url = getattr(object_content,'domain_url','')
+                    if script_height_block == None or y_max==1:
+                      height = 0.75
+                    else:
+                      height = float(script_height_block(object_content))/y_max
+                    list_block.append([marge,(block_stop-block_begin)/(float(len(x_axe[0]))),height,info,
+                                      1-height,url])   
+               # 0.75(height) need to be defined        
+                  marge+=1/float(len(x_axe[0])) 
     else:
-      block_stop=None
-    if isinstance(block_begin,DateTime):    
-        if round(block_begin-DateTime(x_axe[0][0]))!=0:
-          block_left=float(round(block_begin-DateTime(x_axe[0][0])))/round(DateTime(x_axe[0][len(x_axe[0])-1])-DateTime(x_axe[0][0]))
-        else:
+      if method_start != None:
+        block_begin = method_start()
+      else:
+        block_begin = None
+      
+      if method_stop!=None:
+        block_stop= method_stop()
+      else:
+        block_stop=None
+      # if datas are DateTime type we need to do special process.
+      if isinstance(block_begin,DateTime):    
+        if round(block_begin-DateTime(x_axe[0][0]))>0:
+          block_left=float(round(block_begin-DateTime(x_axe[0][0])))/round(
+                     DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+        elif round(block_begin-DateTime(x_axe[0][0]))==0:
           block_left=0
-        if block_stop-DateTime(x_axe[0][0])!=0:            
-          block_right=float(round(block_stop-DateTime(x_axe[0][0])))/round(DateTime(x_axe[0][len(x_axe[0])-1])-DateTime(x_axe[0][0]))
         else:
-          block_right=0                   
-        list_block.append([block_left,block_right-block_left,0.75,info,0.25])
-    else:
-      for i in x_axe[0]:
-        if block_begin==i:
-          list_block.append([marge,(block_stop-block_begin)/(float(len(x_axe[0]))),0.75,info,0.25])   
-        # 0.75(height) need to be defined        
-        marge+=1/float(len(x_axe[0])) 
-    
+          block_left=float(round(block_begin-DateTime(x_axe[0][0])))/round(
+                 DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+
+        if block_stop-DateTime(x_axe[0][0])<=0:
+          wrong_left = 1  #means that the block is outside of x-axis range
+        
+        if block_begin-DateTime(x_axe[0][-1])>=0:            
+          wrong_right = 1 #the same
+      
+        block_right=float(round(block_stop-DateTime(x_axe[0][0])))/round(
+                          DateTime(x_axe[0][-1])-DateTime(x_axe[0][0]))
+        
+        if wrong_left!=1 and wrong_right!=1: # if outside we do not display
+          if script_height_block == None or y_max==1:
+            height = 0.75
+          else:
+            height = float(script_height_block(line_content.getObject()))/y_max  
+          list_block.append([block_left,block_right-block_left,height,info,1-height,''])
+      else:
+        if block_begin !=None:
+          if block_stop !=None:
+            for i in x_axe[0]:
+              if block_begin==i:
+                if script_height_block == None or y_max==1:
+                  height = 0.75
+                else:
+                  height = float(script_height_block(line_content.getObject()))/y_max
+              list_block.append([marge,1/(float(len(x_axe[0]))),height,info,1-height,''])   
+                # 0.75(height) need to be defined        
+              marge+=1/float(len(x_axe[0]))
+          else:
+            for i in x_axe[0]:
+              if isinstance(block_begin,list): 
+                for item in block_begin:
+                  if item == i:
+                    if script_height_block == None or y_max==1:
+                      height = 0.75
+                    else:
+                      height = float(script_height_block(line_content.getObject()))/y_max
+                    list_block.append([marge,1/(float(len(x_axe[0]))),height,info,1-height,''])  
+              marge+=1/float(len(x_axe[0]))
     if list_block!=[]:
-      self.appendActivityBlock(list_block) 
+      self.appendActivityBlock(list_block,list_error,old_delta,REQUEST) 
       
-    if self.soon!=[]:
-      soon_line= line_content.objectValues()
-      print soon_line
+    if self.son!=[]:
+      son_line= line_content.objectValues()
       indic=0
-      while indic != len(soon_line):
+      while indic != len(son_line):
         indic2=0
-        for s in soon_line:
-          if s.getTitle() == self.soon[indic].title:
-            self.soon[indic].insertActivityBlock(s,object_start_method_id,object_stop_method_id,
-                                               x_axe,field,info_center,info_topright,info_topleft,
-                                               info_backleft,info_backright)
+        for s in son_line:
+          if s.getTitle() == self.son[indic].title:
+            
+            self.son[indic].insertActivityBlock(line_content=s,object_start_method_id=object_start_method_id,
+                                                object_stop_method_id=object_stop_method_id,x_axe=x_axe,
+                                                field=field,info_center=info_center,
+                                                info_topright=info_topright,info_topleft=info_topleft,
+                                                info_backleft=info_backleft,info_backright=info_backright,
+                                                list_error=list_error,old_delta=old_delta,REQUEST=REQUEST,
+                                                width_line=width_line,
+                                                script_height_block=script_height_block)
         indic+=1
+  
         
-    
-#*************************************************   
-    
-# class block ***********************************     
+# class block      
 class Block:
-  def __init__(self,types,name,begin,width=0,height=0,text='',content={},marge_top=0):
+  def __init__(self,types,name,begin,width=0,height=0,text='',content={},marge_top=0,id='',url=''):
+    """creates a block object"""
     self.types=types
     self.name=name
     self.begin=begin
@@ -1153,16 +1764,18 @@ class Block:
     self.text=text
     self.content=content #stores info block in a dictionnary
     self.marge_top=marge_top
-    # self.color=color need to be implemented in the future!
-    
+    # self.color=color  should be cool to be implemented in the future...
+    self.id = name
+    self.url = url
+  
   def render(self,line_width,line_height,portal_url,line_begin,y_axis_width,line):
     """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 
+    one defines a width and height parameters (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
@@ -1172,81 +1785,86 @@ class Block:
       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=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,font_height,line,portal_url) # NEED TO BE TESTED !!!
+    return self.buildInfoBlockBody(line_width,block_width,font_width,line_height,font_height,
+                                   line,portal_url)
     
   def render_css(self,line_width,line_height,line,y_axis_width):
+    """used for inserting info inside an activity block"""
     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
+    #checks if the block starts before the beginning of the line
+    if ((line_begin+self.begin*line_width) < line_begin) and self.types!='activity_error':
       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))
+    #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) \
+          and self.types!='activity_error':
+      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,font_width,line)
     
-    return self.buildInfoBlockCss(font_height,line_height,block_width,line_width,font_width,line)   # NEED TO BE TESTED!!
-    
-  #************************************************************************      
-  def addInfoCenter(self,info): #add info in the top left corner of a block    
+
+  def addInfoCenter(self,info): 
+    """add info in center of a block"""    
     self.content['center']=info  
     
-  def addInfoTopLeft(self,info): #add info in the top left corner of a block    
+  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    
+  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    
+  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    
+  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,font_height,line,portal_url):
     """ create the body of the html for displaying info inside a block"""
     string=''
+    #line_height=line_height-10
     already=0
     block_name=''
     length_list_info=0
     info=''
+    curr_url = ''
     for i in self.content:
       if self.content[i]!=None:
         length_list_info += 1
-    
     for i in self.content:
       if length_list_info==5:
         test_height= font_height<=((self.height*line_height)/3)
         test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/3))
       if length_list_info==4 or length_list_info==3:
-        if i=='topright':
-          print '--------'
-          print self.name
-          print line_height
         test_height= font_height<=((self.height*line_height)/2)
         test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/2))
-        if i=='topright':
-          print test_height
-          print test_width 
-          print '---------'
-     
       if length_list_info==2:
         test_height=font_height<=(self.height*line_height)
         test_width= (len(self.content[i]*font_width)<=((block_width*line_width)/2))
       if length_list_info==1: 
         test_height= font_height<=(self.height*line_height)
         test_width= (len(self.content[i]*font_width)<=(block_width*line_width))   
-
       if test_height & test_width:
-        string+='<div id=\"'+self.name+i+'\"><a href=\"'+portal_url+'/'+line.url+'\">'+ self.content[i]
+        if self.url!='':
+          curr_url = self.url
+        else:
+          curr_url = line.url
+        string+='<div id=\"'+self.name+i+'\"><a href=\"'+portal_url+'/'+curr_url+'\">'+ self.content[i]
         string+='</a href></div>\n' 
       else: #one adds interogation.png  
         if ((self.width*line_width>=15) & (self.height*line_height>=15)): 
@@ -1254,40 +1872,89 @@ class Block:
           if already==0 or i=='center':
             block_name=self.name+i
             already=1
-             
     if already==1:
-      string+='<div id=\"'+block_name+'\" title=\"'+info+'\"><a href=\"'+portal_url+'/'+line.url+'\"><img src=\"'+portal_url+'/images/question.png\" height=\"15\" width=\"15\"></a href> '
+      string+='<div id=\"'+block_name+'\" title=\"'+info+'\"><a href=\"'+portal_url+'/'+curr_url+'\">\
+              <img src=\"'+portal_url+'/images/question.png\" height=\"15\" width=\"15\"></a href> '
       string+='</div>\n'   
-         
     return string     
-  #**************************************************
 
-#*******************************************    
+
   def buildInfoBlockCss(self,font_height,line_height,block_width,line_width,font_width,line):
-    """use for creating css code when one needs to add info inside a block"""
+    """used for creating css code when one needs to add info inside a block"""
     string=''
-    already=0
+    already=0#used when we add interro.png 
     list_info_length = 0 #counts number of info inside a block(between 0 and 5)
     for j in self.content:
       if  self.content[j]!= None:
         list_info_length += 1 
     if list_info_length ==0:return ''
 
-    matrix = {('center',5):{'left':2,'top':2},('center',4):{'left':0,'top':0},('center',3):{'left':2,'top':2},('center',2):{'left':2,'top':2},
+    #definition of coefficient for different cases of info display.
+    matrix = {
+    ('center',5):{'left':2,'top':2},
+    ('center',4):{'left':0,'top':0},
+    ('center',3):{'left':2,'top':2},
+    ('center',2):{'left':2,'top':2},
     ('center',1):{'left':2,'top':2},
-    ('topright',5):{'left':1.01,'top':0},('topright',4):{'left':1.01,'top':0},('topright',3):{'left':1.01,'top':0},('topright',2):{'left':1.01,'top':2},('topright',1):{'left':1.01,'top':0},
-    ('topleft',5):{'left':0,'top':0},('topleft',4):{'left':1,'top':1},('topleft',3):{'left':0,'top':0},('topleft',2):{'left':0,'top':0},('topleft',1):{'left':0,'top':0},
-    ('botleft',5):{'left':0,'top':1},('botleft',4):{'left':0,'top':1},('botleft',3):{'left':0,'top':1},('botleft',2):{'left':0,'top':1},('botleft',1):{'left':0,'top':1},
-    ('botright',5):{'left':1.01,'top':1.1},('botright',4):{'left':1.01,'top':1.1},('botright',3):{'left':1.01,'top':1.1},('botright',2):{'left':1.01,'top':1.1},('botright',1):{'left':1.01,'top':1.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},('topright',1):{'left':0,'top':0},
-    ('topleft',5):{'left':0,'top':0},('topleft',4):{'left':1,'top':1},('topleft',3):{'left':0,'top':0},('topleft',2):{'left':0,'top':0},('topleft',1):{'left':0,'top':0},
-    ('botleft',5):{'left':0,'top':1},('topleft',4):{'left':0,'top':1},('botleft',3):{'left':0,'top':1},('botleft',2):{'left':0,'top':1},('botleft',1):{'left':0,'top':1},
-    ('botright',5):{'left':1,'top':1},('botright',4):{'left':0,'top':0},('botright',3):{'left':0,'top':0},('botright',2):{'left':0,'top':0},('botright',1):{'left':1,'top':1}
+    ('topright',5):{'left':1.01,'top':0},
+    ('topright',4):{'left':1.01,'top':0},
+    ('topright',3):{'left':1.01,'top':0},
+    ('topright',2):{'left':1.01,'top':2},
+    ('topright',1):{'left':1.01,'top':0},
+    
+    ('topleft',5):{'left':0,'top':0},
+    ('topleft',4):{'left':1,'top':1},
+    ('topleft',3):{'left':0,'top':0},
+    ('topleft',2):{'left':0,'top':0},
+    ('topleft',1):{'left':0,'top':0},
+    
+    ('botleft',5):{'left':0,'top':1},
+    ('botleft',4):{'left':0,'top':1},
+    ('botleft',3):{'left':0,'top':1},
+    ('botleft',2):{'left':0,'top':1},
+    ('botleft',1):{'left':0,'top':1},
+    
+    ('botright',5):{'left':1.01,'top':1.1},
+    ('botright',4):{'left':1.01,'top':1.1},
+    ('botright',3):{'left':1.01,'top':1.1},
+    ('botright',2):{'left':1.01,'top':1.1},
+    ('botright',1):{'left':1.01,'top':1.1}
+    }   
+    #definition of coefficient for different cases, when info strings are too long,
+    #we use a small picture. The coefficient are suitable for are 15x15px picture. 
+    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},
+    ('topright',1):{'left':0,'top':0},
+    
+    ('topleft',5):{'left':0,'top':0},
+    ('topleft',4):{'left':1,'top':1},
+    ('topleft',3):{'left':0,'top':0},
+    ('topleft',2):{'left':0,'top':0},
+    ('topleft',1):{'left':0,'top':0},
+    
+    ('botleft',5):{'left':0,'top':1},
+    ('botleft',4):{'left':0,'top':1},
+    ('botleft',3):{'left':0,'top':1},
+    ('botleft',2):{'left':0,'top':1}, 
+    ('botleft',1):{'left':0,'top':1},
+    
+    ('botright',5):{'left':1,'top':1},
+    ('botright',4):{'left':0,'top':0},
+    ('botright',3):{'left':0,'top':0},
+    ('botright',2):{'left':0,'top':0},
+    ('botright',1):{'left':1,'top':1}
     }  
+    
     idx= 0
     margin_left=0
     margin_top=0
@@ -1303,30 +1970,23 @@ class Block:
       if top==0:
         margin_top=0  
       else:
-        margin_top = round(((self.height*(line_height-10))/top)-(font_height/top))
-
+        margin_top = round(((self.height*(line_height-10))/top)-(font_height))
       if list_info_length==5:
-        test_height= font_height<=((self.height*line_height)/3)
+        test_height= font_height<=((self.height*(line_height))/3)
         test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/3))
       if list_info_length==4 or list_info_length==3:
-        if i=='topright':
-          print '********'
-          print self.name
-          print line_height
-        test_height= font_height<=((self.height*line_height)/2)
+        test_height= font_height<=((self.height*(line_height))/2)
         test_width= ((len(self.content[i])*font_width)<=((block_width*line_width)/2))
-        if i=='topright':
-          print test_height,test_width
-          print '********'
       if list_info_length==2:
-        test_height=font_height<=(self.height*line_height)
+        test_height=font_height<=(self.height*(line_height))
         test_width= (len(self.content[i]*font_width)<=((block_width*line_width)/2))
       if list_info_length==1: 
-        test_height= font_height<=(self.height*line_height)
+        test_height= font_height<=(self.height*(line_height))
         test_width= (len(self.content[i]*font_width)<=(block_width*line_width))
 
       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'              
+        string+='#'+self.name+i+'{position:absolute;\nmargin-left:'+\
+                 str(margin_left)+'px;\nmargin-top:'+str(margin_top)+'px;\n}\n'              
         line.addBlockInfo(self.name+i)
       else: # we add question.png because the size of the block is not enough
         if ((self.width*line_width>=15) & (self.height*line_height>=15)): 
@@ -1336,27 +1996,26 @@ class Block:
           if left == 0:
             margin_left=0
           else:
-            margin_left=round(((block_width*line_width)/left)-(15/left))
+           margin_left=round(((block_width*line_width)/left)-(15/left))
           if top==0:
             margin_top=0  
           else:
             margin_top=round(((self.height*(line_height-10))/top)-(15/top))
           if i=='center' and list_info_length==3:
-            margin_left=round(((block_width*line_width)/left)-(15/left))  
-            margin_top=round(((self.height*(line_height-10))/top)-(font_height/top))
+            margin_left=round(((block_width*line_width)/left)-(15/left))
+            margin_top=round(((self.height*(line_height-10))/top)-(font_height))
           if i=='center' and list_info_length==2:  
             margin_top=round(((self.height*(line_height-10))/top)-(font_height/top))    
           if already==0 or i=='center':
-            string+='#'+self.name+i+'{position:absolute;\nmargin-left:'+str(margin_left)+'px;\nmargin-top:'+str(margin_top)+'0px;\n}'  
+            string+='#'+self.name+i+'{position:absolute;\nmargin-left:'+str(margin_left)+\
+                    'px;\nmargin-top:'+str(margin_top)+'0px;\n}'  
             block_disp=self.name+i
             already=1
-    return string  
- #####################################################
- 
- 
-            
+    return string
+    
+  def get_error_message(self,err_type):
+    return 'incorrect block'
 PlanningBoxWidgetInstance = PlanningBoxWidget()        
- 
           
 class PlanningBox(ZMIField):
     meta_type = "PlanningBox"
@@ -1366,10 +2025,10 @@ class PlanningBox(ZMIField):
     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'))
+        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):
+    def render_css(self, value=None, REQUEST=None):      
       return self.widget.render_css(self,'',value,REQUEST)
-              
\ No newline at end of file