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