]> Creatis software - bbtk.git/blob - kernel/src/bbtkComplexBlackBox.cxx
012a03f24c743a67d2bb440c32cd45d21d3cecc0
[bbtk.git] / kernel / src / bbtkComplexBlackBox.cxx
1 /*=========================================================================
2                                                                                 
3 Program:   bbtk
4 Module:    $RCSfile: bbtkComplexBlackBox.cxx,v $
5 Language:  C++
6 Date:      $Date: 2008/04/08 06:59:29 $
7 Version:   $Revision: 1.8 $
8                                                                                 
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE.  See the above copyright notices for more information.
16                                                                                
17 =========================================================================*/
18
19
20 /**
21  *  \file 
22  *  \brief class bbtk::ComplexBlackBox : user defined complex black boxes
23  */
24 #include "bbtkComplexBlackBox.h"
25 #include "bbtkBlackBoxDescriptor.h"
26 #include "bbtkFactory.h"
27 #include "bbtkConfigurationFile.h"
28
29 namespace bbtk
30 {
31
32
33   //=======================================================================
34   /// Usefull constructor 
35   ComplexBlackBox::ComplexBlackBox(const std::string &name,
36                                    ComplexBlackBoxDescriptor* desc)
37     : BlackBox(name),
38       mDescriptor(desc)
39   {
40     bbtkDebugMessageInc("Kernel",9,
41                         "ComplexBlackBox::ComplexBlackBox(\""
42                         <<name<<"\")"<<std::endl);
43     bbAllocateConnectors();
44     bbtkDebugDecTab("Kernel",9);
45   }
46   //=======================================================================
47
48   //=======================================================================
49   /// Constructor from an existing box (copy) with a new name 
50   ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from, 
51                                    const std::string &name)
52     : BlackBox(from,name),
53       mDescriptor(from.mDescriptor),
54      mExecutionList(from.mExecutionList)    
55   {
56     bbtkDebugMessageInc("Kernel",9,
57                         "ComplexBlackBox::ComplexBlackBox(\""
58                         <<from.bbGetName()<<"\",\""
59                         <<name<<"\")"<<std::endl);
60
61     bbtkDebugMessageInc("Kernel",9,"* Cloning Black Boxes"<<std::endl);
62     BlackBoxMapType::const_iterator i;
63     for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i ) 
64       {
65         bbtkDebugMessageInc("Kernel",9,"* Cloning \""<<i->first<<"\""<<std::endl);
66         BlackBox* B = i->second->bbClone(i->second->bbGetName());
67         bbUnsafeAddBlackBox(B);
68         
69         bbtkDebugDecTab("Kernel",9);
70       }
71     bbtkDebugDecTab("Kernel",9);
72    
73     bbtkDebugMessageInc("Kernel",9,"* Cloning Connections"<<std::endl);
74     ConnectionListType::const_iterator j;
75     for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j ) 
76       {
77         bbtkDebugMessageInc("Kernel",9,"* Cloning \""<<
78                             (*j)->GetFullName()<<"\""<<std::endl);
79
80         BlackBox* bbfrom = bbGetBlackBox( (*j)->GetBlackBoxFrom()->bbGetName() );
81         BlackBox* bbto = bbGetBlackBox( (*j)->GetBlackBoxTo()->bbGetName() );
82         Connection* c = mDescriptor->GetFactory()-> 
83           NewConnection( bbfrom, 
84                          (*j)->GetBlackBoxFromOutput(), 
85                          bbto, 
86                          (*j)->GetBlackBoxToInput() );
87         
88         bbAddConnection(c);
89
90         bbtkDebugDecTab("Kernel",9);
91       }
92     bbtkDebugDecTab("Kernel",9);
93
94     bbAllocateConnectors();
95     bbtkDebugDecTab("Kernel",9);    
96   }
97   //=======================================================================
98
99   //======================================================================= 
100   ///  Destructor
101   ComplexBlackBox::~ComplexBlackBox()
102   {
103     bbtkDebugMessageInc("Kernel",9,
104                         "ComplexBlackBox::~ComplexBlackBox() ["
105                         <<bbGetFullName()<<"]"<<std::endl);
106     
107     bbtkDebugMessageInc("Kernel",9,"* Delete Connections"<<std::endl);
108     ConnectionListType::iterator j;
109     for ( j = mConnectionList.begin(); j != mConnectionList.end(); ++j ) 
110       {
111         bbtkDebugMessageInc("Kernel",9,"* Delete \""<<
112                             (*j)->GetFullName()<<"\""<<std::endl);
113         delete *j;
114         bbtkDebugDecTab("Kernel",9);
115       }
116     bbtkDebugDecTab("Kernel",9);
117
118     
119     bbtkDebugMessageInc("Kernel",9,"* Delete Black Boxes"<<std::endl);
120     BlackBoxMapType::iterator i;
121     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
122       {
123         bbtkDebugMessageInc("Kernel",9,"* Delete \""<<i->first<<"\""<<std::endl);
124         i->second->bbDelete();
125         bbtkDebugDecTab("Kernel",9);
126       }
127     bbtkDebugDecTab("Kernel",9);
128     //    bbtkDebugMessage("Kernel",9,"EO ComplexBlackBox::~ComplexBlackBox  ["
129     //               <<bbGetFullName()<<"]"<<std::endl);
130
131     
132     this->bbDesallocateConnectors();
133     bbtkDebugDecTab("Kernel",9);   
134   } 
135   //=======================================================================
136
137   //=========================================================================
138   /// Allocates the i/o connectors of the black box
139   void ComplexBlackBox::bbAllocateConnectors()
140   {  
141     bbtkDebugMessageInc("Kernel",8,
142                         "ComplexBlackBox::bbAllocateConnectors() ["
143                         <<bbGetFullName()<<"]"
144                         <<std::endl);   
145
146     // Input connectors
147     const BlackBoxDescriptor::InputDescriptorMapType& imap 
148       = bbGetDescriptor()->GetInputDescriptorMap(); 
149     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
150     for ( i = imap.begin(); i != imap.end(); ++i )                      
151       {                                                                 
152         bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
153         // Redirect the connector to the internal box connector
154         // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
155         ComplexBlackBoxInputDescriptor* d = 
156           (ComplexBlackBoxInputDescriptor*)i->second;
157         // Get the internal box connector
158         BlackBoxInputConnector* c = 
159           bbUnsafeGetBlackBox ( d->GetTarget() )
160           ->bbGetInputConnectorMap()[ d->GetInput() ];
161         
162         bbGetInputConnectorMap()[i->second->GetName()] = c;
163 //new BlackBoxInputConnector();
164       }                                                                 
165
166     // Output connectors
167     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
168       = bbGetDescriptor()->GetOutputDescriptorMap();                   
169     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
170     for ( o = omap.begin(); o != omap.end(); ++o )
171       {                                                 
172         bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
173         // Redirect the connector to the internal box connector
174         // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
175         ComplexBlackBoxOutputDescriptor* d = 
176           (ComplexBlackBoxOutputDescriptor*)o->second;
177         // Get the internal box connector
178         BlackBoxOutputConnector* c = 
179           bbUnsafeGetBlackBox ( d->GetTarget() )
180           ->bbGetOutputConnectorMap()[ d->GetOutput() ];
181
182         bbGetOutputConnectorMap()[o->second->GetName()] = c;
183         //new BlackBoxOutputConnector();
184       }
185     bbtkDebugDecTab("Kernel",8);  
186   }
187   //=========================================================================
188
189
190   //=========================================================================
191   /// Desallocates the i/o connectors of the black box
192   void ComplexBlackBox::bbDesallocateConnectors()
193   {
194     bbtkDebugMessageInc("Kernel",8,
195                         "ComplexBlackBox::DesallocateConnectors()"
196                         <<std::endl);                                   
197
198     // The connectors have not been allocated by the complex box 
199     // but by the internal boxes. Hence **DO NOT** desallocate !
200     // just clear the maps to avoid that 
201     // BlackBox::bbDesallocateConnectors delete the connectors
202     bbGetInputConnectorMap().clear();
203     bbGetOutputConnectorMap().clear();
204
205     bbtkDebugDecTab("Kernel",8);  
206
207   }
208   //=========================================================================
209
210   //=======================================================================
211   BlackBox* ComplexBlackBox::bbClone(const std::string& name)
212   {
213     bbtkDebugMessageInc("Kernel",9,
214                         "ComplexBlackBox::bbClone(\""<<name<<"\") ["
215                         <<bbGetFullName()<<"]"<<std::endl);
216     
217     ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
218     
219     bbtkDebugDecTab("Kernel",9);   
220
221     return CBB;
222   }
223   //=======================================================================
224
225   //=======================================================================
226   /// Main processing method of the box.
227   /// Executes the box so that its outputs are up-to-date on exit
228   void ComplexBlackBox::bbExecute(bool force)
229   {
230     bbtkDebugMessageInc("Process",1,
231                         "ComplexBlackBox::bbExecute() ["
232                         <<bbGetFullName()<<"]"<<std::endl);
233
234
235     Wx::BeginBusyCursor();
236     
237     if (mExecutionList.size() != 0) 
238       {
239         
240         std::vector<std::string>::const_iterator i;
241         for (i=mExecutionList.begin(); 
242              i!=mExecutionList.end();
243              ++i) 
244           {
245             bbtkDebugMessage("Process",2," -> Executing '"<<*i<<"'"<<std::endl);
246             mBlackBoxMap[*i]->bbExecute(force);
247           }
248       }
249     else 
250       {
251         std::map<std::string, BlackBox*>::iterator i;
252         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
253           {
254             i->second->bbExecute(force);
255           }
256       } 
257
258     Wx::EndBusyCursor();
259     
260
261     bbtkDebugDecTab("Process",1);
262     
263   }
264   //==================================================================
265
266   //==================================================================
267   void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
268   {
269     bbtkDebugMessage("Process",3,
270                         "ComplexBlackBox::bbSetModifiedStatus("
271                      <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
272
273     c->GetBlackBox()->bbSetModifiedStatus(c);
274
275     bbtkDebugMessage("Process",3,
276                      "EO ComplexBlackBox::bbSetModifiedStatus("
277                      <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
278   }
279   //==================================================================
280
281   //==================================================================
282   void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
283   {
284         bbtkDebugMessageInc("Kernel",9,
285                         "ComplexBlackBox::bbAddToExecutionList(\""
286                         <<name<<"\") ["
287                         <<bbGetFullName()<<"]"<<std::endl);
288
289         mExecutionList.push_back( name );
290
291      bbtkDebugDecTab("Kernel",9);   
292
293   }
294   //==================================================================
295
296   //==================================================================
297   IOStatus ComplexBlackBox::bbBackwardUpdate(Connection* caller)
298   {
299     bbtkDebugMessageInc("Process",1,
300                         "ComplexBlackBox::bbBackwardUpdate("
301                         <<(caller?caller->GetFullName():"0")<<") ["
302                         <<bbGetFullName()<<"]"<<std::endl);
303
304     if (caller==0)
305       {
306         bbtkInternalError("ComplexBlackBox::bbBackwardUpdate called with caller=0");
307       }
308
309     if (bbGetExecuting()) 
310       {
311         bbtkWarning(bbGetFullName()<<" : Cyclic execution stopped");
312         return UPTODATE;
313       }
314     bbSetExecuting(true);
315
316     IOStatus s = UPTODATE;
317     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
318       = bbGetDescriptor()->GetOutputDescriptorMap(); 
319     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i 
320       = omap.find(caller->GetBlackBoxFromOutput());
321     if (i!=omap.end())
322       { 
323         // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
324         ComplexBlackBoxOutputDescriptor* d = 
325           (ComplexBlackBoxOutputDescriptor*)i->second;
326         // Get the internal box 
327         BlackBox* b = bbUnsafeGetBlackBox ( d->GetTarget() );
328         // Calls BackwardUpdate on it
329         bbtkDebugMessageInc("Process",2,"Internal box connected to output : "<<d->GetTarget()<<std::endl);
330         // Because internal box can also be a complex box we have to 
331         // temporarily change the connection BlackBoxFromOutput to the 
332         // mapped one
333         
334         //      std::string oldout = caller->GetBlackBoxFromOutput();
335         //      std::cout << "oldout = "<<oldout<<std::endl;
336         //      std::cout << "tmpout = "<<d->GetOutput()<<std::endl;
337         //      caller->SetBlackBoxFromOutput(d->GetOutput());
338         //
339         Connection newcaller(*caller);
340         newcaller.SetBlackBoxFromOutput(d->GetOutput());
341         IOStatus s1 = b->bbBackwardUpdate(&newcaller);
342         newcaller.Clear();
343         // restore old output
344         //      caller->SetBlackBoxFromOutput(oldout);
345
346         // ??? STATUS OF CBBs ???
347         // ??? Here it is only the final status of the boxes connected to the output 
348         if (s1==MODIFIED) s=MODIFIED;
349         bbtkDebugDecTab("Process",2);
350       }
351     else 
352       {
353         bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
354       }
355     bbtkDebugDecTab("Process",1);
356
357     bbSetExecuting(false);
358
359     return s;
360   }
361   //==================================================================
362
363
364   //==================================================================
365   Data ComplexBlackBox::bbGetOutput( const std::string &name )
366   {
367     bbtkDebugMessageInc("Data",7,
368                         "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
369                         <<bbGetFullName()<<"]"<<std::endl);
370
371     ComplexBlackBoxOutputDescriptor* d = 
372       (ComplexBlackBoxOutputDescriptor*)
373       bbGetDescriptor()->GetOutputDescriptor(name);
374     
375     Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
376
377
378     bbtkDebugDecTab("Data",7);
379     return p;
380   }
381   //==================================================================
382
383   //==================================================================
384   ///  Gets the input Data of a given name
385   Data ComplexBlackBox::bbGetInput( const std::string &name ) 
386   {
387     bbtkDebugMessageInc("Data",7,
388                         "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
389                         <<bbGetFullName()<<"]"<<std::endl);  
390
391     ComplexBlackBoxInputDescriptor* d = 
392       (ComplexBlackBoxInputDescriptor*)
393       bbGetDescriptor()->GetInputDescriptor(name);
394
395     Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
396
397     bbtkDebugDecTab("Data",7);
398     return p;
399   }
400   //==================================================================
401
402   //==================================================================
403   ///  Sets the data of the output called <name>
404   void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
405   {
406     bbtkDebugMessageInc("Data",7,
407                         "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
408                         <<bbGetFullName()<<"]"<<std::endl); 
409
410     ComplexBlackBoxOutputDescriptor* d = 
411       (ComplexBlackBoxOutputDescriptor*)
412       bbGetDescriptor()->GetOutputDescriptor(name);
413     
414     bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
415
416     bbtkDebugDecTab("Data",7);
417   }
418   //==================================================================
419   
420   //==================================================================
421   ///  Sets the data of the input called <name>
422   void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
423                                     bool setModified)
424   {
425     bbtkDebugMessageInc("Data",7,
426                         "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
427                         <<bbGetFullName()<<"]"<<std::endl);  
428
429     ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
430       bbGetDescriptor()->GetInputDescriptor(name);
431
432     bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
433
434     bbtkDebugDecTab("Data",7);
435   }
436   //==================================================================
437
438  
439   //==================================================================
440   ///  Sets the data of the input called <name>
441   void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name, 
442                                                      void* data,
443                                                      bool setModified)
444   {
445     bbtkDebugMessageInc("Data",7,
446                         "ComplexBlackBox::bbBruteForceSetInputPointer('"
447                         <<name<<"',"<<data<<") ["
448                         <<bbGetFullName()<<"]"<<std::endl);  
449
450     ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
451       bbGetDescriptor()->GetInputDescriptor(name);
452
453     bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
454                                                                data,
455                                                                setModified);
456
457     bbtkDebugDecTab("Data",7);
458   }
459   //==================================================================
460
461   //==================================================================
462   /// Adds the black box to the complex box
463   void ComplexBlackBox::bbAddBlackBox( BlackBox* b)
464   {
465     bbtkDebugMessageInc("Kernel",7,
466                         "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
467                         <<"\") ["
468                         <<bbGetFullName()<<"]"<<std::endl);  
469     
470     if ( bbUnsafeGetBlackBox(b->bbGetName()) ) 
471       {
472         bbtkError("a black box called \""<<b->bbGetName()
473                   <<"\" already exists");
474       }
475     b->bbSetParent(this);
476     mBlackBoxMap[b->bbGetName()] = b;
477
478     bbtkDebugDecTab("Kernel",7);
479   }
480   //==================================================================
481
482   //==================================================================
483   /// Adds the black box to the complex box (unsafe)
484   void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox* b)
485   {
486     bbtkDebugMessageInc("Kernel",7,
487                         "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
488                         <<"\") ["
489                         <<bbGetFullName()<<"]"<<std::endl);  
490     
491     b->bbSetParent(this);
492     mBlackBoxMap[b->bbGetName()] = b;
493
494     bbtkDebugDecTab("Kernel",7);
495   }
496   //==================================================================
497
498   //==================================================================
499   /// Removes the black box from the complex box
500   void ComplexBlackBox::bbRemoveBlackBox( const std::string& name )
501   {
502     bbtkDebugMessageInc("Kernel",7,
503                         "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
504                         <<bbGetFullName()<<"]"<<std::endl);  
505
506     bbtkError("ComplexBlackBox::RemoveBlackBox not implemented");
507
508     bbtkDebugDecTab("Kernel",7);
509   }
510   //==================================================================
511
512   //==================================================================
513   /// Adds the connection to the complex box
514   void ComplexBlackBox::bbAddConnection( Connection* c)
515   {
516     bbtkDebugMessageInc("Kernel",7,
517                         "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
518                         <<bbGetFullName()<<"]"<<std::endl);  
519
520     mConnectionList.push_back(c);
521
522     bbtkDebugDecTab("Kernel",7);
523   }
524   //==================================================================
525   //    void RemoveConnection( );
526
527   //==================================================================
528   /// Returns the black box with name <name>
529   BlackBox* ComplexBlackBox::bbGetBlackBox( const std::string& name )
530   {
531     bbtkDebugMessageInc("Kernel",9,
532                         "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
533                         <<bbGetFullName()<<"]"<<std::endl);  
534
535     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
536     if ( i == mBlackBoxMap.end() ) 
537       {
538         bbtkError("the black box \""<<name<<"\" does not exist");
539       }
540
541     bbtkDebugDecTab("Kernel",9);
542     return i->second;
543   }
544   //==================================================================
545
546   //==================================================================
547   /// Returns the black box with name <name> : does not throw an exception 
548   /// if it does not exist but return a null pointer
549   BlackBox* ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
550   {
551     bbtkDebugMessageInc("Kernel",9,
552                         "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
553                         <<bbGetFullName()<<"]"
554                         <<std::endl);  
555
556     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
557     if ( i == mBlackBoxMap.end() ) 
558       {
559         bbtkDebugDecTab("Kernel",9);
560         return 0;
561       }
562
563     bbtkDebugDecTab("Kernel",9);
564     return i->second;
565     
566   }
567   //==================================================================
568
569   //==================================================================
570   void ComplexBlackBox::bbPrintBlackBoxes()
571   {
572     bbtkDebugMessageInc("Kernel",9,
573                         "ComplexBlackBox::PrintBlackBoxes() ["
574                         <<bbGetFullName()<<"]"
575                         <<std::endl);  
576
577     BlackBoxMapType::iterator i;
578     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
579       {
580         bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
581       }
582
583     bbtkDebugDecTab("Kernel",9);
584   }
585   //==================================================================
586
587
588  
589   //=========================================================================
590   /// Virtual
591   void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
592   {
593     if (inputoutput)
594       {
595         fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
596       } else {
597       fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
598     } // if inputoutput
599   }
600   //=========================================================================
601
602
603   //=========================================================================
604   BlackBox *ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
605   {
606     BlackBox *blackbox=NULL;
607     std::string subname="";
608     std::string restname="";
609     std::string delimiters(">");
610     // Skip delimiters at beginning.
611     std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
612     // Find first "non-delimiter".
613     std::string::size_type pos     = blackboxname.find_first_of(delimiters, lastPos);
614             
615     // Found a token, add it to the vector.
616     subname = blackboxname.substr(lastPos, pos - lastPos);
617     restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
618
619     if (restname==subname)
620     {
621            restname="";
622     }
623
624     BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
625     if ( i == mBlackBoxMap.end() ) 
626     {
627            blackbox = NULL;
628     } 
629     else 
630     {
631        blackbox = i->second;
632        if (restname!="")
633             {
634              blackbox = blackbox->bbFindBlackBox(restname);
635             }
636     }
637     return blackbox;
638   }
639   //=========================================================================
640
641   //=========================================================================
642   void ComplexBlackBox::bbInsertHTMLGraph(  std::ofstream& s, 
643                                             int detail, 
644                                             int level,
645                                             bool instanceOrtype,
646                                             const std::string& output_dir,
647                                             bool relative_link )
648   {
649     
650     std::string directory(output_dir);
651
652     if (output_dir.length() == 0) 
653     {
654            // Don't pollute the file store with  "temp_dir" directories ... 
655            std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
656            directory =  default_temp_dir + "/" + "temp_dir";
657     }
658     
659     std::string simplefilename  (this->bbGetTypeName()+"_"+this->bbGetName());
660     std::string simplefilename_png (simplefilename+".png");
661     std::string filename           (directory+"/"+simplefilename);
662     std::string filename_png       (filename+".png");
663     std::string filename_cmap      (filename+".cmap");
664     std::string filename_dot       (filename+".dot");
665
666     std::string filename_png2   ("\""   + filename_png  + "\"");
667     std::string filename_cmap2  ("\""   + filename_cmap + "\"");
668     std::string filename_dot2   ("\""   + filename_dot  + "\"");
669     
670
671     std::string command1 ("dot -T png -o "  
672                           + filename_png2  + " " + filename_dot2);
673     std::string command1a("dot -T cmap -o " 
674                           + filename_cmap2 + " " + filename_dot2);
675
676     // 1. Generating .dot file
677     FILE *ff;
678     ff = fopen(filename_dot.c_str(),"w");
679     fprintf(ff,"digraph bbtk_graph{\n");
680     fprintf(ff,"rankdir=LR%s\n",";");
681     fprintf(ff,"node [shape=record]%s\n",";");
682
683     this->bbWriteDotFileBlackBox(ff,this,detail,level,
684                                  instanceOrtype,
685                                  relative_link );
686
687     fprintf(ff,"}\n");
688     fclose(ff);
689
690     // 2. Executing .dot file -> png
691     system( command1.c_str() );   
692     // 3. Executing .dot file -> cmap
693     system( command1a.c_str() );  
694     
695     // 4. HTML code insertion
696     // 4.1 image
697     (s) << "<center><img src=\"" << simplefilename_png 
698          <<   "\" border=\"0\" usemap=\"#map_"<< simplefilename 
699          <<"\" alt=\"\"></center>\n";
700
701     // 4.2 map
702     (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
703     FILE *ff2;
704     char c;
705     ff2=fopen(filename_cmap.c_str(),"r");
706     while (!feof(ff2))
707     {
708            c=fgetc(ff2);
709            if (c!=-1)
710            {
711               (s) << c;
712            }
713     }
714     (s) << "</map>\n\n";
715     
716     // End
717   }
718   //=========================================================================
719
720
721   //=========================================================================
722   /// Write Graphviz-dot description in file 
723   void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
724                                                BlackBox *parentblackbox, 
725                                                int detail, int level,
726                                                bool instanceOrtype,
727                                                bool relative_link )   
728   {
729     std::string tmp1;
730     std::string valueStr("");
731     Package *package = this->bbGetDescriptor()->GetPackage(); 
732
733     if (package!=NULL)
734     {
735       if (relative_link)
736              tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
737            else 
738              tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
739     } 
740     else 
741     {
742            tmp1 = "Caspitas";
743     }
744
745     std::string tmp2=bbGetTypeName();
746     std::string url(tmp1 + "#" + tmp2 );        
747     fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
748
749     if (!(   (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
750     {
751            fprintf( ff , "  URL = \"%s\" %s",url.c_str(),";");
752     }
753
754     std::string boxname="["+bbGetTypeName()+"]";
755     if (this!=parentblackbox)
756     {
757        if (detail==0)
758             {
759           boxname=bbGetName();
760        } 
761        else 
762        {
763           boxname = bbGetName();
764           boxname = boxname + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
765             }
766
767     }
768     fprintf( ff , "  label = \"%s\"%s\n",  boxname.c_str() ,";");
769
770
771
772     //  fprintf( ff , "  style=filled%s\n",";");
773     //  fprintf( ff , "  color=grey%s\n",";");
774     fprintf( ff , "  node [style=filled]%s\n",";");
775     fprintf( ff , "  fillcolor=grey%s\n",";");
776     fprintf( ff , "  edge [color=blue]%s\n",";");
777
778
779     // Labels Salida
780     std::string labelStr1;
781     std::string labelStr2;
782     labelStr1 = boxname + "\\n(output)" ; 
783     labelStr2 = " | {{ ";
784     bool tmp; 
785     tmp=false;
786     OutputConnectorMapType::iterator i;
787
788     const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
789     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;      
790     for ( o = omap.begin();  o != omap.end(); ++o ) 
791       {
792         if (tmp==true)
793           {
794             labelStr2=labelStr2+" | ";
795           }
796         tmp=true;
797         if (instanceOrtype==true)
798           {
799             valueStr = this->bbGetOutputAsString(o->second->GetName()/*
800                                                                    ,factory*/) + " = ";
801           } 
802         labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
803       }
804
805     labelStr2 = labelStr2+ " } }";
806
807
808
809     if (detail==1)
810       {
811         labelStr1 = labelStr1 + labelStr2;
812       }
813
814     if (tmp){
815       fprintf(ff,"  " );
816       bbWriteDotInputOutputName(ff,false,detail,level);
817       fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
818     }
819
820
821     // label Entrada
822     labelStr1 = boxname + "\\n(input)" ; 
823     labelStr2 = " | {{ "; 
824     tmp=false;
825     InputConnectorMapType::iterator ii;
826
827     const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap();  
828     BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
829     for ( iii = imap.begin();  iii != imap.end(); ++iii ) 
830       {
831         if (tmp==true)
832           {
833             labelStr2=labelStr2+" | ";
834           }
835         tmp=true;
836         if (instanceOrtype==true)
837           {
838             valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
839           } 
840         labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
841       }
842
843
844     labelStr2 = labelStr2+ " } }";
845     if (detail==1)
846       {
847         labelStr1 = labelStr1 + labelStr2;
848       }
849     if (tmp){
850       fprintf(ff,"  " );
851       bbWriteDotInputOutputName(ff,true,detail,level);
852       fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
853     }
854
855
856     // Body
857     BlackBoxMapType::iterator j;
858     for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j ) 
859       {
860         if (level>-1)
861           {
862             j->second->bbWriteDotFileBlackBox(ff,parentblackbox,detail,
863                                               level-1,
864                                               instanceOrtype,
865                                               relative_link);
866           }
867       }
868
869     fprintf( ff , "}\n\n");
870
871     fprintf( ff , "  edge[color=blue]%s\n",";");
872
873     if (level>-1)
874       {
875         // Relation Input  with the inside BlackBox of the this ComplexBlackbox
876         ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
877         ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
878         for ( xx = idmt.begin(); xx != idmt.end(); ++xx ) 
879           {
880             ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
881
882             fprintf(ff,"  ");
883             bbWriteDotInputOutputName(ff,true,detail,level);
884             if (detail==1)
885               {
886                 fprintf(ff,":%s",cbbid->GetName().c_str() );
887               }
888             fprintf(ff,"->" );
889             BlackBox *bb = bbGetBlackBox( cbbid->GetTarget() ); 
890             bb->bbWriteDotInputOutputName(ff,true,detail,level);
891             if (detail==1)
892               {
893                 fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
894               }
895           }// for xx
896
897
898
899         fprintf(ff,"\n \n");
900
901
902
903         // Relation Output ComplexBlackBox
904         ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
905         ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
906         for ( yy = odmt.begin(); yy != odmt.end(); ++yy ) 
907           {
908             ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
909             fprintf(ff,"  ");
910             BlackBox *bb = bbGetBlackBox( cbbod->GetTarget() ); 
911             bb->bbWriteDotInputOutputName(ff,false,detail,level);
912             if (detail==1)
913               {
914                 fprintf(ff,":%s", cbbod->GetOutput().c_str() );
915               }
916             fprintf(ff,"->" );
917             bbWriteDotInputOutputName(ff,false,detail,level);
918             if (detail==1)
919               {
920                 fprintf(ff,":%s",cbbod->GetName().c_str() );
921               }
922             fprintf(ff,"\n");
923           } // for yy
924
925       } // if level
926
927
928
929         // Relation from the out side of this ComplexBlackBox with its Inputs
930     if (this!=parentblackbox) {
931       for ( ii = bbGetInputConnectorMap().begin(); 
932             ii != bbGetInputConnectorMap().end(); ++ii ) 
933         {
934           if (ii->second)
935             {
936               Connection* con = ii->second->GetConnection();
937               if (con!=NULL){
938                 BlackBox *a=con->GetBlackBoxFrom();
939                 BlackBox *b=con->GetBlackBoxTo();
940                 fprintf(ff,"  ");
941                 a->bbWriteDotInputOutputName(ff,false,detail,level);
942                 if (detail==1)
943                   {
944                     fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str());
945                   }
946                 fprintf(ff,"->");
947                 b->bbWriteDotInputOutputName(ff,true,detail,level);
948                 if (detail==1)
949                   {
950                     fprintf(ff,":%s",con->GetBlackBoxToInput().c_str());
951                   }
952                 fprintf(ff,"%s\n",";");
953               } // if con
954             } // if second
955         } // for
956     } // if parentblackbox
957   }
958   //=========================================================================
959   
960
961
962
963   /*
964
965   //=======================================================================
966   /// Generates the list of the packages of which its depends 
967   /// (cause an internal box belongs to it)
968   void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
969   {
970     deps.clear;
971     BlackBoxMapType::iterator i;
972     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
973       {
974         deps.push_back(i->second->bbGetDescriptor()->GetPackage());
975       }
976
977   }
978   //=======================================================================
979   */
980 }