00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00031 
00032 
00033 
00034 
00035 #ifdef __GNUG__
00036 #pragma implementation "Element.cpp"
00037 #endif
00038 
00039 
00040 #include "mc/mcprec.h"
00041 #ifdef __BORLANDC__
00042     #pragma hdrstop
00043 #endif
00044 
00045 #ifndef mcPRECOMP
00046     #include <wx/dcscreen.h>
00047 
00048  #include "mc/EmptyBox.h"
00049  #include "mc/Number.h"
00050  #include "mc/Bracket.h"
00051  #include "mc/Fraction.h"
00052  #include "mc/Function.h"
00053  #include "mc/Radical.h"
00054  #include "mc/Text.h"
00055  #include "mc/Symbol.h"
00056  #include "mc/Operator.h"
00057  #include "mc/AddSubOp.h" 
00058  #include "mc/MultDivOp.h" 
00059  #include "mc/Monomial.h"
00060  #include "mc/Parenthesis.h"
00061 #endif
00062 
00063 
00064 
00065 wxBrush *mcElementHelpers::sgui_pSelectionBrush = NULL;
00066 wxBrush *mcElementHelpers::sgui_pActivationBrush = NULL;
00067 mcStyleArray *mcElementHelpers::sgui_pDefaultStyles = NULL;
00068 int mcElementHelpers::sgui_nAdditionalActivationSpaceLeftRight = 2;
00069 mcElement *mcElementHelpers::sdata_pElem[];
00070 
00071 
00072 mcElement mcEmptyElement;
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 #ifdef __MCDEBUG__
00083 
00084 void mcElementHelpers::data_Check() const
00085 {
00086  
00087  mcASSERT(mdata_nProperties >= 0, wxT("Not valid"));
00088  mcASSERT(mdata_nID >= 0, wxT("Not valid"));
00089 
00090  
00091  for (int i=0,max=data_GetChildrenCount(); i < max; i++) {
00092 
00093   const mcElement &tocheck = data_GetConstChild(i);
00094 
00095   
00096   
00097 
00098 
00099   
00100   tocheck.data_Check();
00101  }
00102 }
00103 
00104 wxString mcElementHelpers::data_GetDebug(int indent, long flags) const
00105 {
00106  wxString str, tmp;
00107 
00108  
00109  
00110  
00111 
00112  
00113  str += wxString(wxT(' '), indent);
00114 
00115  
00116  if (flags & mcELEMENT_DBG_EXPDEPTH)
00117   str += wxString::Format(wxT("EXPDEPTH: %2d  "), gui_GetExpDepth());
00118 
00119  if (flags & mcELEMENT_DBG_SELECTION &&
00120   mcMathCore::Get()->isGUIEnabled())
00121   str += wxString::Format(wxT("SELECTED: %s  "), 
00122     (gui_isSelected() ? wxT("YES") : wxT("NO ")));
00123 
00124  if (flags & mcELEMENT_DBG_ID)
00125   str += wxString::Format(wxT("ID: %2d  "), data_GetID());
00126 
00127  
00128  str += data_Debug(flags);
00129  str = wxIndent(str, indent);
00130 
00131  
00132  return str;
00133 }
00134 
00135 void mcElement::data_CheckContainer() const
00136 {
00137  
00138  
00139  if (data_GetRefData()) {
00140   mcElementHelpers *helpers = (mcElementHelpers *)data_GetRefData();
00141   mcUNUSED(helpers);  
00142  
00143   
00144   
00145   mcASSERT(data_isValidContainerFor(helpers->data_GetType()), 
00146    wxT("Invalid container (this is a ") +
00147    data_GetDebugName() + 
00148    wxT(") for the given helper class (") + 
00149    helpers->data_GetDebugName() +
00150    wxT("Helpers) !!"));
00151  }
00152 }
00153 
00154 void mcElement::data_Check() const
00155 {
00156  
00157  data_CheckContainer();
00158 
00159  
00160  if (chlp()) chlp()->data_Check();
00161 }
00162 
00163 #endif  
00164 
00165 
00166 mcElementHelpers::mcElementHelpers()
00167 {
00168  
00169  
00170  
00171  
00172  mdata_nID = mcElementHelpers::data_GenID();
00173  
00174  
00175  mdata_nProperties = mcEP_NOPROPERTIES;
00176  mgui_nExpDepth = 0;
00177 }
00178 
00179 void mcElementHelpers::data_Init()
00180 {
00181  
00182  if (mcMathCore::Get()->isGUIEnabled()) gui_Init();
00183  if (mcMathCore::Get()->isMathEnabled()) math_Init();
00184  if (mcMathCore::Get()->isIOEnabled()) io_Init();
00185 }
00186 
00187 bool mcElementHelpers::io_Init(const wxString &str)
00188 {
00189  wxString err;
00190  int n;
00191  
00192  
00193  if (!mcMathCore::Get()->isIOEnabled())
00194   return FALSE;
00195  if (io_isBeginChar(str) == FALSE)
00196   return FALSE;
00197  return io_ImportInlinedExpr(str, &n, err);
00198 }
00199 
00200 void mcElementHelpers::gui_OnRecalcSize(wxSize old)
00201 {
00202  
00203  if (old == mgui_sz)
00204   return;
00205  
00206  
00207  
00208  
00209  
00210 } 
00211 
00212 void mcElementHelpers::gui_SetStyleArray(const mcStyleArray *p)
00213 {
00214  
00215  if (!mcMathCore::Get()->isGUIEnabled())
00216   return;
00217  
00218  mgui_pStyleArray = p;
00219  
00220  
00221  for (int i=0; i < data_GetChildrenCount(); i++)
00222   data_GetChild(i).gui_SetStyleArray(p);
00223 }
00224 
00225 mcElement &mcElementHelpers::data_GetElemFromID(int id) const 
00226 {
00227  
00228  
00229  
00230  for (int i=0; i < data_GetChildrenCount(); i++) {
00231   mcElement &p = data_GetConstChild(i).data_GetElemFromID(id);
00232   if (p != mcEmptyElement)
00233    return p;
00234  }
00235  
00236  return mcEmptyElement;
00237 }
00238 
00239 
00240 void mcElementHelpers::data_AddRecursiveProperty(mcElementType t, int p, void *val1, void *val2)
00241 {
00242  if (data_GetType() == t)
00243   data_AddProperty(p, val1, val2);
00244  
00245  
00246  for (int i=0; i < data_GetChildrenCount(); i++)
00247   data_GetChild(i).data_AddRecursiveProperty(t, p, val1, val2);
00248 }
00249 
00250 bool mcElementHelpers::data_hasRecursiveProperty(mcElementType t, int p) const
00251 {
00252  if (data_GetType() == t)
00253   return ((mdata_nProperties & p) != 0);
00254  
00255  
00256  for (int i=0; i < data_GetChildrenCount(); i++)
00257   if (data_GetConstChild(i).data_hasRecursiveProperty(t, p))
00258    return TRUE;
00259   return FALSE;
00260 }
00261 
00262 void mcElementHelpers::data_RemoveRecursiveProperty(mcElementType t, int p)
00263 {
00264  if (data_GetType() == t)
00265   mdata_nProperties &= ~p;
00266  
00267  
00268  for (int i=0; i < data_GetChildrenCount(); i++)
00269   data_GetChild(i).data_RemoveRecursiveProperty(t, p);
00270 }
00271 
00272 void mcElementHelpers::data_Update()
00273 {
00274  
00275 
00276  
00277  for (int i=0; i < data_GetChildrenCount(); i++)
00278   data_GetChild(i).data_Update(); 
00279 }
00280 
00281 bool mcElementHelpers::data_AddChildrenTo(mcElement p)
00282 {
00283  if (p.data_GetType() != data_GetType())
00284   return FALSE;
00285   
00286  for (int i=0, max=data_GetChildrenCount(); i < max; i++)
00287   p.data_SetChild(i, data_GetChild(i));
00288  return TRUE; 
00289 }
00290 
00291 int mcElementHelpers::data_GetChildIdx(const mcElement &p) const
00292 {  
00293  for (int i=0,max=data_GetChildrenCount(); i < max; i++)
00294   if (data_GetConstChild(i) == p)
00295    return i; 
00296   
00297  return -1;
00298 }
00299 
00300 mcElement &mcElementHelpers::data_GetChild(int n)
00301 { return (mcElement &)data_GetConstChild(n);}
00302 
00303 const mcElement &mcElementHelpers::data_GetConstChild(int) const
00304 { return mcEmptyElement;}
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 mcElement::mcElement(const mcElementHelpers *helpers)
00315 { 
00316  
00317  data_SetRefData((mcObjectRefData *)helpers);
00318  
00319  
00320  if (data_GetRefData())
00321   data_GetRefData()->data_IncRefCount();
00322 #ifndef mcENABLE_COW
00323  if (data_GetRefData())
00324   data_MakePrivateCopy();  
00325 #endif
00326 }
00327 
00328 mcElement::~mcElement()
00329 { 
00330 #ifdef mcENABLE_COW_DEBUG
00331  if (data_GetRefData() && mcMathCore::isOk())
00332   mcMathCore::Get()->m_nMaxSharing = 
00333   mcMAX(mcMathCore::Get()->m_nMaxSharing, chlp()->data_GetRefCount());
00334 #endif
00335 }
00336 
00337 void mcElement::data_Ref(const mcObject &toclone)
00338 {
00339  mcObject::data_Ref(toclone);
00340 
00341  
00342  
00343  
00344  
00345  
00346  
00347 #ifdef __MCDEBUG__
00348  wxLogNull logNo;
00349  data_CheckContainer();
00350 #endif
00351 }
00352 
00353 void mcElementHelpers::Init()
00354 {
00355  for (int t=0; t < mcNUM_ELEMENT_TYPES; t++)
00356   sdata_pElem[t] = NULL;
00357 
00358  
00359  data_UpdateElemArray();
00360 }
00361 
00362 void mcElementHelpers::Cleanup()
00363 {  
00364  for (int t=0; t < mcNUM_ELEMENT_TYPES; t++)
00365   mcSAFE_DELETE(sdata_pElem[t]);
00366 }
00367 
00368 void mcElementHelpers::data_UpdateElemArray()
00369 {
00370  
00371  
00372  
00373  for (int t=0; t < mcNUM_ELEMENT_TYPES; t++) {
00374   mcSAFE_DELETE(sdata_pElem[t]);
00375 
00376   
00377   
00378   sdata_pElem[t] = new mcElement(data_NewElem((mcElementType)t));
00379  }
00380 }
00381 
00382 
00383 #define mcDEFINE_ALLOCATOR(x)       \
00384  if (towrap)           \
00385   return x(towrap);        \
00386  else            \
00387   return x(); 
00388 
00389 #define mcDEFINE_SPECIAL_ALLOCATOR(x, param1)   \
00390  if (towrap)           \
00391   return x(towrap);        \
00392  else            \
00393   return x(param1); 
00394 
00395 mcElement mcElementHelpers::data_NewElem(mcElementType type, const mcElementHelpers *towrap)
00396 {
00397  
00398 
00399  
00400  
00401  switch (type) {
00402  case mcET_NUMBER:
00403   mcDEFINE_ALLOCATOR(mcNumber)
00404  case mcET_PARENTHESIS:
00405   mcDEFINE_ALLOCATOR(mcParenthesis)
00406  case mcET_BRACKET:
00407   mcDEFINE_ALLOCATOR(mcBracket)
00408  case mcET_RADICAL:
00409   mcDEFINE_ALLOCATOR(mcRadical)
00410  case mcET_FRACTION:
00411   mcDEFINE_ALLOCATOR(mcFraction)
00412  case mcET_SYMBOL:
00413   mcDEFINE_ALLOCATOR(mcSymbol)
00414  case mcET_FUNCTION:
00415   mcDEFINE_ALLOCATOR(mcFunction)
00416  case mcET_TEXT:
00417   mcDEFINE_ALLOCATOR(mcText)
00418  case mcET_EMPTYBOX:
00419   mcDEFINE_ALLOCATOR(mcEmptyBox)
00420  case mcET_ADDOP:
00421   mcDEFINE_SPECIAL_ALLOCATOR(mcAddSubOp, mcET_ADDOP);
00422  case mcET_SUBOP:
00423   mcDEFINE_SPECIAL_ALLOCATOR(mcAddSubOp, mcET_SUBOP);
00424  case mcET_MULTOP:
00425   mcDEFINE_SPECIAL_ALLOCATOR(mcMultDivOp, mcET_MULTOP);
00426  case mcET_DIVOP:
00427   mcDEFINE_SPECIAL_ALLOCATOR(mcMultDivOp, mcET_DIVOP);
00428  case mcET_POLYNOMIAL:
00429   mcDEFINE_ALLOCATOR(mcPolynomial)
00430  case mcET_MONOMIAL:
00431   mcDEFINE_ALLOCATOR(mcMonomial)
00432  default:
00433   mcASSERT(0, wxT("The allocation of an undefined class was requested"));
00434  }
00435 
00436  return NULL;
00437 }
00438 
00439 
00440 
00441 #define SCAN_REGISTERED_CLASSES(fnc, params)     \
00442     \
00443  for (int i=0; i < mcNUM_ELEMENT_TYPES; i++) {  \
00444   if (sdata_pElem[i]->fnc(params) != FALSE) {    \
00445                 \
00446       \
00447    return (mcElementType)i;       \
00448   }              \
00449  }               \
00450                 \
00451    \
00452  return mcET_INVALID;
00453 
00454 
00455 
00456 mcElementType mcElementHelpers::gui_isKeyBeginKey(const mcKey &key) {
00457  SCAN_REGISTERED_CLASSES(gui_isBeginKey, key);
00458 }
00459 
00460 mcElementType mcElementHelpers::io_isCharBeginChar(const wxString &str) {
00461  SCAN_REGISTERED_CLASSES(io_isBeginChar, str);
00462 }
00463 
00464 mcElementType mcElementHelpers::io_isTagBeginTag(const wxXml2Node &tag) {
00465  SCAN_REGISTERED_CLASSES(io_isBeginTag, tag);
00466 }
00467 
00468 wxString mcElementHelpers::data_GetGlobalMemoryInfo()
00469 {
00470  wxString res;
00471 
00472  for (int i=0; i < mcNUM_ELEMENT_TYPES; i++) {
00473 
00474   res += wxString::Format(wxT("Class number #%d: %d\n"), 
00475    i,
00476    sdata_pElem[i]->data_GetMemoryInfo());
00477  }
00478 
00479  return res;
00480 }
00481 
00482 int mcElementHelpers::data_GenID(bool bFirstMember)
00483 {
00484  
00485  static int l=0, r=0xFFFF;
00486  if (bFirstMember)
00487   return l++;
00488  return r++;
00489 }
00490 
00491 mcObjectRefData *mcElement::data_MakePrivateCopy()  
00492 {
00493  const mcElementHelpers *h = chlp();
00494 
00495  
00496  
00497  if (h->data_GetRefCount() == 1)
00498   return (mcElementHelpers *)h;
00499 
00500  
00501 #ifdef mcENABLE_COW_DEEPDEBUG
00502  mcLOG(wxT("mcElementHelpers::data_MakePrivateCopy"));
00503 #endif
00504  data_UnRef();
00505 
00506  
00507  data_SetRefData(h->data_Clone());
00508 
00509  
00510  return (mcElementHelpers *)data_GetRefData(); 
00511 }
00512 
00513 void mcElementHelpers::gui_UpdateExpDepth()
00514 {
00515  
00516  
00517  
00518  
00519  
00520  
00521  
00522  
00523  
00524  
00525  
00526  
00527  gui_RecalcSize();
00528 }
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 bool mcElementHelpers::data_isSameAs(const mcElementHelpers *p) const
00563 {
00564  bool b = TRUE;
00565 
00566  
00567  
00568 
00569  
00570  b &= (data_GetType() == p->data_GetType());
00571  b &= (mdata_nProperties == p->mdata_nProperties);
00572  if (!b) return FALSE;
00573 
00574  
00575  for (int i=0; i < data_GetChildrenCount(); i++)
00576   if (!data_GetConstChild(i).data_isSameAs(p->data_GetConstChild(i)))
00577    return FALSE;
00578 
00579  return TRUE;
00580 }
00581 
00582 
00583 
00584 void mcElementHelpers::data_DeepCopy(const mcElementHelpers *p)
00585 {
00586  
00587  
00588  mcASSERT(data_GetType() == p->data_GetType(), wxT("Cannot perform deep copy !!"));
00589 
00590  
00591  mdata_nProperties = p->mdata_nProperties;
00592  
00593  mgui_bSelected = p->mgui_bSelected;
00594  mgui_sz = p->mgui_sz;
00595  mgui_pStyleArray = p->mgui_pStyleArray;
00596  mgui_nExpDepth = p->mgui_nExpDepth;
00597 }
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 void mcElementHelpers::gui_Init() 
00609 {
00610  
00611  
00612  mgui_sz.Set(-1, -1);
00613  
00614  
00615  mgui_bSelected = FALSE;
00616  
00617  
00618  if (!mcMathCore::Get()->isGUIEnabled())
00619   return;
00620  
00621  
00622  
00623  
00624  
00625  
00626  mcASSERT(sgui_pDefaultStyles != NULL,
00627   wxT("pDefaultStyles must always be a valid array !!!"));
00628  
00629  
00630  
00631  mgui_pStyleArray = sgui_pDefaultStyles;
00632 
00633  gui_RecalcSize();
00634 }
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 mcElement mcElementHelpers::gui_GetSelection() const
00674 {
00675  
00676  
00677  return mcElement(this);
00678 }
00679 
00680 mcElement &mcElementHelpers::gui_GetActiveElem(int x, int y, const wxPoint &pt) const
00681 {
00682  wxScreenDC tmp;
00683 
00684  
00685  int n = gui_Draw(tmp, x, y, mcDRW_USEPOINT, pt);
00686 
00687  
00688  
00689  if (n != mcDRW_NOACTIVEELEM && n != mcDRW_ONSELECTION)
00690   return data_GetElemFromID(n);
00691  return mcEmptyElement;
00692 }
00693 
00694 void mcElementHelpers::gui_RecalcSize()
00695 {
00696  wxSize old = mgui_sz;
00697  gui_DoRecalcSize();
00698 
00699  
00700  gui_OnRecalcSize(old);
00701 }
00702 
00703 void mcElementHelpers::gui_DeepRecalcSize()
00704 {
00705  mcGUILOG(wxT("mcElementHelpers::gui_DeepRecalcSize [%s]"), mcTXTTHIS);
00706 
00707  
00708  for (int i=0; i < data_GetChildrenCount(); i++)
00709   data_GetChild(i).gui_DeepRecalcSize();
00710 
00711  
00712  gui_RecalcSize();
00713 }
00714 
00715 void mcElementHelpers::gui_SelectAll()
00716 {
00717  
00718  for (int i=0; i < data_GetChildrenCount(); i++)
00719   data_GetChild(i).gui_SelectAll();
00720 
00721  
00722  gui_Select();
00723 }
00724 
00725 void mcElementHelpers::gui_DeSelect()
00726 {
00727  
00728  for (int i=0; i < data_GetChildrenCount(); i++)
00729   data_GetChild(i).gui_DeSelect();
00730 
00731  
00732  mgui_bSelected = FALSE;
00733 }
00734 
00735 bool mcElementHelpers::gui_isAllSelected() const
00736 {
00737  
00738  for (int i=0; i < data_GetChildrenCount(); i++)
00739   if (!data_GetConstChild(i).gui_isAllSelected())
00740    return FALSE;
00741 
00742  
00743  return gui_isSelected();
00744 }
00745 
00746 void mcElementHelpers::gui_DeleteSelection()
00747 {
00748  mcASSERT(!gui_isAllSelected(), 
00749   wxT("This element is completely selected: it should be removed by the caller"));
00750 
00751  
00752  for (int i=0; i < data_GetChildrenCount(); i++)
00753   data_GetChild(i).gui_DeleteSelection();
00754 
00755  
00756  gui_RecalcSize();
00757 }
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 void mcElementHelpers::gui_SetAsExpOf(const mcElement &p)
00768 {
00769  if (p != mcEmptyElement)
00770   mgui_nExpDepth = p.gui_GetExpDepth()+1;
00771 
00772  
00773  gui_UpdateExpDepth();
00774 }
00775 
00776 void mcElementHelpers::gui_SetAtSameLevelOf(const mcElement &p)
00777 {
00778  if (p != mcEmptyElement)
00779   mgui_nExpDepth = p.gui_GetExpDepth();
00780 
00781  
00782  gui_UpdateExpDepth();
00783 }
00784 
00785 void mcElementHelpers::gui_InitDefaultStyles()
00786 {
00787  mcGUILOG(wxT("mcElementHelpers::gui_InitDefaultStyles"));
00788 
00789  
00790  gui_DeleteDefaultStyles();
00791  
00792  
00793  sgui_pDefaultStyles = new mcStyleArray();
00794  mcStyle *p = new mcStyle();
00795 
00796  
00797  for (int j=0; j < sgui_pDefaultStyles->GetCount(); j++) {
00798   
00799   
00800   
00801   
00802   
00803   
00804   
00805   
00806   
00807   
00808   
00809   
00810   
00811 #if defined(__WXMSW__)
00812   
00813   
00814   wxString face1 = wxT("Lucida Sans Unicode");  
00815   wxString face2 = wxT("Tahoma");
00816   wxString face3 = wxT("Verdana");
00817   const int size = 25;
00818   const int size2 = 20;
00819   
00820 
00821 
00822 
00823 
00824   
00825 #else
00826   
00827   wxString face1 = wxT("Lucida");
00828   wxString face2 = wxT("Lucida");
00829   wxString face3 = wxT("Lucida");
00830   const int size = 25;
00831   const int size2 = 25;
00832   
00833 #endif
00834   
00835   
00836   wxString num = wxString::Format(wxT("%d-%s-%d-%d-%d"), wxSWISS,
00837    face1.c_str(), size/(j+1), wxNORMAL, wxNORMAL);
00838   
00839   wxString fnc = wxString::Format(wxT("%d-%s-%d-%d-%d"), wxSWISS,
00840    face2.c_str(), size/(j+1), wxNORMAL, wxITALIC);
00841   
00842   wxString sym = wxString::Format(wxT("%d-%s-%d-%d-%d"), wxROMAN,
00843    face3.c_str(), size/(j+1), wxNORMAL, wxITALIC);
00844   
00845   wxString text = wxString::Format(wxT("%d-%s-%d-%d-%d"), wxSWISS,
00846    face2.c_str(), size2/(j+1), wxBOLD, wxNORMAL);
00847   
00848   wxString spec = wxString::Format(wxT("%d-%s-%d-%d-%d"), wxSWISS,
00849    wxT("MathStudio Special"), size/(j+1), wxBOLD, wxNORMAL);
00850   
00851   
00852   p->SetTextSettingsFor(mcET_NUMBER, mcINITWX(0xFF0000), *wxWHITE, num);
00853   p->SetTextSettingsFor(mcET_FUNCTION, mcINITWX(0x4080FF), *wxWHITE, fnc);
00854   p->SetTextSettingsFor(mcET_SYMBOL, mcINITWX(0x14A03C), *wxWHITE, sym);
00855   p->SetTextSettingsFor(mcET_TEXT, mcINITWX(0x329C7A), *wxWHITE, text);
00856   
00857   
00858   
00859   p->SetTextSettingsFor(mcET_ADDOP, mcINITWX(0x0), *wxWHITE, num);
00860   
00861   
00862   p->SetSpecialTextSettings(mcINITWX(0x0), *wxWHITE, spec);
00863   
00864   
00865   mcASSERT(p->Ok(), wxT("Problems in style creation"));
00866   
00867   
00868   sgui_pDefaultStyles->Set(p, j); 
00869  }
00870 
00871  
00872  
00873  delete p;
00874 }
00875 
00876 double mcElementHelpers::gui_GetPointSize()
00877 {
00878  
00879  
00880  static double pxperpoint = 0;
00881 
00882  if (pxperpoint == 0) {
00883 
00884   wxScreenDC dc;
00885 
00886   
00887   
00888   dc.SetMapMode(wxMM_POINTS);
00889   pxperpoint = dc.LogicalToDeviceYRel(72);
00890  }
00891 
00892  return pxperpoint;
00893 }
00894 
00895 void mcElementHelpers::gui_DeleteDefaultStyles()
00896 {
00897  
00898  mcSAFE_DELETE(sgui_pDefaultStyles);
00899 }
00900 
00901 double mcElementHelpers::gui_PointSize2Pixels(double pointsize)
00902 {
00903  
00904  
00905  
00906  
00907  
00908  return (pointsize * gui_GetPointSize());
00909 }
00910 
00911 double mcElementHelpers::gui_Pixels2PointSize(double pixels)
00912 {
00913  
00914  return (72.0 * pixels / gui_GetPointSize());
00915 }
00916 
00917 int mcElementHelpers::gui_GetBaseOffsety(int exph) const
00918 {
00919  
00920  
00921  return (int)((exph/100.0)*50.);
00922 }
00923 
00924 int mcElementHelpers::gui_GetSubscriptOffsety(int baseh) const
00925 {
00926  
00927  
00928  return (int)((baseh/100.0)*60.);
00929 }
00930 
00931 const mcStyle *mcElementHelpers::gui_GetStyleForThis() const {
00932  
00933  return mgui_pStyleArray->gui_GetStyleFor(this);
00934 }
00935 
00936 const mcStyle *mcElementHelpers::gui_GetDefaultStyle(int n) {  
00937  return sgui_pDefaultStyles->Get(n);
00938 }
00939 
00940 const mcStyle *mcElementHelpers::gui_GetStyle(int n) const {
00941  
00942  return mgui_pStyleArray->Get(n);
00943 }
00944 
00945 
00946 
00947 
00948 
00949 
00950 void mcElementHelpers::gui_SelectStyle(wxDC &hDC) const {
00951  const mcStyle *p = gui_GetStyleForThis();
00952 
00953  
00954  
00955  
00956  mcASSERT(hDC.Ok(), wxT("Invalid DC"));
00957 
00958  
00959  p->gui_Select(hDC, this);
00960 }
00961 
00962 int mcElementHelpers::gui_GetThickness(wxDC *dc) const {
00963  mcGUILOG(wxT("mcElementHelpers::gui_GetThickness"));
00964  bool bClean = FALSE;
00965 
00966  if (dc == NULL) {
00967   dc = new wxScreenDC();
00968   bClean = TRUE;
00969  }
00970 
00971  
00972  gui_SelectStyle(*dc);
00973  int nWeight = dc->GetFont().GetWeight();
00974  int nHeight = dc->GetFont().GetPointSize();
00975 
00976  
00977  if (bClean)
00978   delete dc;
00979 
00980  
00981  
00982  return (int)(nWeight/527.5 + nHeight/12.8);
00983 }
00984 
00985 wxSize mcElementHelpers::gui_GetSizeOf(wxDC *hDC, const wxString &str) {
00986  mcGUILOG(wxT("mcElementHelpers::gui_GetSizeOf [%s]"), str.c_str());
00987  bool bClean=FALSE;
00988  int w=0, h=0;
00989  
00990  
00991  if (hDC == NULL) {
00992   hDC = new wxScreenDC();
00993   bClean = TRUE;
00994  }
00995 
00996  
00997  if (str.IsEmpty()) return wxSize(0,0);
00998 
00999  
01000 #ifdef __WXGTK20__
01001  mcGUILOG(wxT("------------------ Using the buggy wxScreenDC function -----------------"));
01002  hDC->GetTextExtent(str, &w, &h);
01003 #else
01004  hDC->GetTextExtent(str, &w, &h);
01005 #endif
01006  mcASSERT(w != 0 && h != 0, wxT("Cannot retrieve character size"));
01007 
01008  
01009  if (bClean)
01010   delete hDC; 
01011 
01012  
01013  return wxSize(w, h);
01014 }
01015 
01016 int mcElementHelpers::gui_GetWidthOf(wxDC *h, const wxString &str) {
01017  return gui_GetSizeOf(h, str).GetWidth();
01018 }
01019 
01020 int mcElementHelpers::gui_GetHeightOf(wxDC *h, const wxString &str) {
01021  return gui_GetSizeOf(h, str).GetHeight();
01022 }
01023 
01024 wxSize mcElementHelpers::gui_GetSizeOfChar(wxDC *hDC, const mcElement &p) const {
01025  return wxSize(mcElementHelpers::gui_GetWidthOfChar(hDC, p),
01026       mcElementHelpers::gui_GetHeightOfChar(hDC, p));
01027 }
01028 
01029 int mcElementHelpers::gui_GetWidthOfChar(wxDC *hDC, const mcElement &p) const {
01030  mcGUILOG(wxT("mcElementHelpers::gui_GetWidthOfChar"));
01031  bool bClean=FALSE;
01032  int w;
01033 
01034  
01035  if (hDC == NULL) {
01036   hDC = new wxScreenDC();
01037   bClean = TRUE;
01038  }
01039 
01040  
01041  
01042  if (p != NULL)
01043   p.gui_SelectStyle(*hDC);
01044 
01045  
01046  w = hDC->GetCharWidth();
01047  mcASSERT(w != 0, wxT("Cannot retrieve character size"));
01048 
01049  
01050  if (bClean)
01051   delete hDC;
01052 
01053  
01054  return w;
01055 }
01056 
01057 int mcElementHelpers::gui_GetHeightOfChar(wxDC *hDC, const mcElement &p) const {
01058  mcGUILOG(wxT("mcElementHelpers::sgui_GetHeightOfChar"));
01059  bool bClean=FALSE;
01060  int h;
01061 
01062  
01063  if (hDC == NULL) {
01064   hDC = new wxScreenDC();
01065   bClean = TRUE;
01066  }
01067 
01068  
01069  
01070  if (p != NULL)
01071   p.gui_SelectStyle(*hDC);
01072 
01073  
01074  h = hDC->GetCharHeight();
01075  mcASSERT(h != 0, wxT("Cannot retrieve character size"));
01076 
01077  
01078  if (bClean)
01079   delete hDC;
01080 
01081  
01082  return h;
01083 }
01084 
01085 
01086 
01087 
01088 
01089 
01090 
01091 
01092 
01093 void mcElementHelpers::io_PostProcessChildren()
01094 {
01095  for (int i=0; i < data_GetChildrenCount(); i++)
01096   data_GetChild(i).hlp()->io_PostProcess();
01097 }
01098 
01099 
01100 
01101 
01102 
01103 
01104 
01105 
01106 
01107 mcElement mcElement::operator^(const mcRealValue &r) const
01108 { mcElement ret(*this); ret.math_RaiseTo(mcPolynomial(r)); return ret; }
01109 
01110 void mcElementHelpers::math_SimpleAdd(const mcElement &p, bool add)
01111 {
01112  mcMATHLOG(wxT("mcElementHelpers::math_SimpleAdd [%s] - simple adding with [%s]"),
01113     mcTXTTHIS, mcTXT(p));
01114  mcBasicOpRes r = math_Add(p, NULL, add);
01115  mcASSERT(r == mcBOR_REMOVE_OPERAND, 
01116    wxT("The operation could not be completely performed: ")
01117    wxT("the given operand has not been completely merged in *this"));
01118  mcUNUSED(r);  
01119 }
01120 
01121 void mcElementHelpers::math_SimpleMultiplyBy(const mcElement &p)
01122 {
01123  mcMATHLOG(wxT("mcElementHelpers::math_SimpleMultiplyBy [%s] - simple multiplying by [%s]"),
01124     mcTXTTHIS, mcTXT(p));
01125  mcBasicOpRes r = math_MultiplyBy(p, NULL);
01126  mcASSERT(r == mcBOR_REMOVE_OPERAND, 
01127    wxT("The operation could not be completely performed: ")
01128    wxT("the given operand has not been completely merged in *this"));
01129  mcUNUSED(r);  
01130 }
01131 
01132 void mcElementHelpers::math_SimpleDivideBy(const mcElement &p)
01133 {
01134  mcMATHLOG(wxT("mcElementHelpers::math_SimpleDivideBy [%s] - simple dividing by [%s]"),
01135     mcTXTTHIS, mcTXT(p));
01136  mcBasicOpRes r = math_DivideBy(p, NULL);
01137  mcASSERT(r == mcBOR_REMOVE_OPERAND, 
01138    wxT("The operation could not be completely performed: ")
01139    wxT("the given operand has not been completely merged in *this"));
01140  mcUNUSED(r);  
01141 }
01142 
01143 void mcElementHelpers::math_SimpleRaiseTo(const mcPolynomial &p)
01144 {
01145  mcMATHLOG(wxT("mcElementHelpers::math_SimpleRaiseTo [%s] - simple raising by [%s]"),
01146     mcTXTTHIS, mcTXT(p));
01147  mcBasicOpRes r = math_RaiseTo(p);
01148  mcASSERT(r == mcBOR_REMOVE_OPERAND, 
01149    wxT("The operation could not be completely performed: ")
01150    wxT("the given operand has not been completely merged in *this"));
01151  mcUNUSED(r);  
01152 }
01153 
01154 bool mcElementHelpers::math_isExpAllowed(mcElement p) 
01155 {
01156  
01157  
01158   return TRUE;
01159  
01160 }
01161 
01162 bool mcElementHelpers::math_isSubAllowed(mcElement )
01163 {
01164  
01165  return TRUE;
01166 }
01167 
01168 void mcElementHelpers::math_SetExp(const mcPolynomial &pol)
01169 {
01170  
01171  
01172  
01173  
01174  for (int i=0; i<data_GetChildrenCount(); i++)
01175   data_GetChild(i).math_SetExp(pol);
01176 }
01177 
01178 mcBasicOpRes mcElementHelpers::math_MakeReciprocal(mcElement *replacement)
01179 {
01180  mcFraction f;
01181  f.data_GetNum().math_WrapNumber(1);
01182  f.data_GetDen().math_WrapSimple(mcElement(this));
01183  *replacement = f;
01184 
01185  return mcBOR_REPLACE_BOTH;
01186 }
01187 
01188 mcExpSimRes mcElementHelpers::math_MaxSimplify(long flags)
01189 {
01190  mcExpSimRes retflag = mcESR_NOTFINISHED;
01191  int cycles=0;
01192 
01193  
01194  
01195  while (retflag != mcESR_DONE) {
01196   retflag = math_Simplify(flags, NULL);  
01197   cycles++;
01198   
01199   if (cycles >= mcELEMENTMATH_MAX_PROCESS_CYCLES)  
01200    return mcESR_NOTFINISHED;  
01201  }
01202 
01203  return mcESR_DONE;
01204 }
01205 
01206 bool mcElementHelpers::math_isMaxSimplified(long flags) const
01207 {
01208  mcExpSimRes retflag = mcESR_NOTFINISHED;
01209  int cycles=0;
01210 
01211  
01212  mcElementHelpers *backup = data_Clone();
01213 
01214  
01215  
01216  while (retflag != mcESR_DONE) {
01217   retflag = backup->math_Simplify(flags, NULL);  
01218   cycles++;
01219 
01220   if (cycles >= mcELEMENTMATH_MAX_PROCESS_CYCLES)  
01221    break;
01222  }
01223 
01224  
01225  
01226  return (cycles == 1);
01227 }
01228 
01229 mcRealValue mcElementHelpers::math_GetTotalLenght() const
01230 {
01231  
01232  
01233  
01234  
01235  mcRealValue l = math_GetLenght();
01236  
01237  for (int i=0; i < data_GetChildrenCount(); i++)
01238   l += data_GetConstChild(i).math_GetTotalLenght();
01239   
01240  return l;
01241 }
01242 
01243 bool mcElementHelpers::math_isFinite() const
01244 {
01245  mcRealValue res = math_Evaluate();
01246  if (res.math_isFinite())
01247   return TRUE;
01248  return FALSE;
01249 }
01250 
01251 bool mcElementHelpers::math_isValidMath() const
01252 {
01253  switch (data_GetType()) {
01254  case mcET_INVALID:
01255  case mcET_PARENTHESIS:
01256  case mcET_EMPTYBOX:
01257 
01258 
01259 
01260 
01261  case mcET_TEXT:
01262   return FALSE;  
01263 
01264  default:
01265   break;
01266  }
01267 
01268  
01269  for (int i=0; i < data_GetChildrenCount(); i++)
01270   if (!data_GetConstChild(i).math_isValidMath())
01271    return FALSE;
01272 
01273  
01274  return TRUE;
01275 }
01276 
01277 bool mcElementHelpers::math_isListedBeforeOf(const mcElement &p) const
01278 {
01279  if (math_GetOrderPos() < p.math_GetOrderPos())
01280   return TRUE;
01281  return FALSE;
01282 }
01283 
01284 mcMonomial mcElementHelpers::math_GetFactors() const
01285 {
01286  mcMonomial pol;
01287  pol.math_WrapSimple(this);
01288 
01289  return pol;
01290 }
01291 
01292 
01293 
01294 
01295 
01296 
01297 
01298 
01299 bool mcElementHelpers::math_Contains(const mcElement &p, long flags) const
01300 { return math_Find(0, p, flags) != mcEmptyElement; }
01301 
01302 bool mcElementHelpers::math_ContainsNumber(const mcRealValue &num,
01303              const mcPolynomial &exp) const
01304 {
01305  mcNumber n(num);
01306 
01307  
01308  if (exp != mcEmptyPolynomial)
01309   n.data_SetExpSub(TRUE, exp);
01310 
01311  return math_Contains(n);
01312 }
01313 
01314 bool mcElementHelpers::math_ContainsSymbol(const mcSymbolProperties *prop,
01315              const mcPolynomial &exp) const
01316 {
01317  mcSymbol safe(prop->data_GetSafeLinkedSym());
01318  mcASSERT(safe.data_isOk(), wxT("Invalid safe symbol ?"));
01319 
01320  
01321  if (exp != mcEmptyPolynomial)
01322   safe.data_SetExpSub(TRUE, exp);
01323 
01324  return math_Contains(safe);
01325 }
01326 
01327 bool mcElementHelpers::math_ContainsOneOf(const mcSymbolArray *arr) const
01328 {
01329  int max = arr->data_GetCount();
01330  for (int i=0; i < max; i++) {
01331 
01332   
01333   
01334   
01335 
01336   
01337   const mcSymbolProperties *curr = arr->data_GetSymbol(i);
01338 
01339   
01340   
01341 
01342   if (math_Contains(curr->data_GetSafeLinkedSym())) {
01343 
01344    
01345    return TRUE;
01346   }
01347  }
01348 
01349  
01350  return FALSE;
01351 }
01352 
01353 bool mcElementHelpers::math_ContainsUnknowns() const
01354 { return math_ContainsOneOf(&mcSymbol::arrUnknowns); }
01355 
01356 bool mcElementHelpers::math_ContainsConstants() const
01357 { return math_ContainsOneOf(&mcSymbol::arrConstants); }
01358 
01359 bool mcElementHelpers::math_ContainsParameters() const
01360 { return math_ContainsOneOf(&mcSymbol::arrParameters); }
01361 
01362 bool mcElementHelpers::math_ContainsSymbols() const
01363 {
01364  
01365  return math_ContainsUnknowns() || 
01366    math_ContainsConstants() ||
01367    math_ContainsParameters();
01368 }
01369 
01370 bool mcElementHelpers::math_ContainsInvalidSymbols() const
01371 {
01372  
01373  return math_ContainsOneOf(&mcSymbol::arrUnregistered);
01374 }
01375 
01376 bool mcElementHelpers::math_isConstant() const
01377 {
01378  
01379  
01380  
01381  return !math_ContainsParameters() && !math_ContainsUnknowns();
01382 }
01383 
01384 int mcElementHelpers::math_GetSymbolList(mcSymbol **arr, int size, const mcSymbol &tofind) const
01385 {
01386  int n = 0;
01387  
01388 
01389  
01390  const mcElement p = math_Find(n, tofind);
01391 
01392 
01393 
01394 
01395 
01396 
01397 
01398 
01399 
01400 
01401 
01402 
01403  return n;
01404 }
01405 
01406 int mcElementHelpers::math_GetSymbolList(mcSymbol **arr, int size, mcSymbolProperties &tofind) const
01407 {
01408  mcSymbol tmp;
01409  tmp.data_LinkWith(&tofind);
01410 
01411  return math_GetSymbolList(arr, size, tmp);
01412 }
01413 
01414 bool mcElementHelpers::math_CompareThisOnly(const mcElement &p, long) const
01415 {
01416  
01417  
01418  
01419  return (data_GetType() == p.data_GetType());
01420 }
01421 
01422 mcElement mcElementHelpers::math_Find(int n, const mcElement &p, long flags) const
01423 {
01424  mcASSERT(n >= 0, wxT("Invalid occurrence to find"));
01425  int k = n;
01426 
01427  
01428  return math_RecursiveFind(k, p, flags);
01429 }
01430 
01431 mcElement mcElementHelpers::math_FindInChildrenOnly(int n, const mcElement &p, long flags) const
01432 {
01433  mcASSERT(n >= 0, wxT("Invalid occurrence to find"));
01434  int k = n;
01435 
01436  
01437  return math_RecursiveFindInChildrenOnly(k, p, flags);
01438 }
01439 
01440 int mcElementHelpers::math_NonRecursiveFindInChildren(int n, 
01441      const mcElement &p, long flags) const
01442 {
01443  mcASSERT(n >= 0, wxT("Invalid occurrence to find"));
01444 
01445  
01446  for (int i=0,max=data_GetChildrenCount(); i<max; i++) {
01447     
01448   if (data_GetConstChild(i).math_Compare(p, flags)) {
01449    
01450    
01451    if (--n == -1)
01452     return i;
01453 
01454    
01455   }
01456  }
01457  
01458  
01459  return -1;
01460 }
01461 
01462 mcElement mcElementHelpers::math_RecursiveFindInChildrenOnly(int &n, 
01463         const mcElement &p, long flags) const
01464 {
01465  mcASSERT(n >= 0, wxT("Invalid occurrence to find"));
01466 
01467  
01468  for (int i=0,max=data_GetChildrenCount(); i<max; i++) {
01469 
01470   
01471   const mcElement &res = data_GetConstChild(i).chlp()->math_RecursiveFind(n, p, flags);
01472 
01473   
01474   
01475   
01476   
01477   if (n == -1) {
01478 
01479    
01480    if (res != mcEmptyElement) 
01481     return res;
01482 
01483    
01484    
01485    
01486    mcASSERT(flags & mcFIND_PARENT, wxT("Something wrong"));
01487 
01488    
01489    
01490    
01491    mcASSERT(math_NonRecursiveFindInChildren(n+1, p, flags & ~mcFIND_PARENT) != -1,
01492     wxT("Cannot find the element tofind in the children of *this..."));
01493    return mcElement(this);
01494   }
01495  }
01496 
01497  return mcEmptyElement;
01498 }
01499 
01500 
01501 
01502 
01503 
01504 
01505 mcElement mcElementHelpers::math_RecursiveFind(int &n, 
01506         const mcElement &p, long flags) const
01507 {
01508  mcASSERT(n >= 0, wxT("Invalid occurrence to find"));
01509 
01510  
01511  
01512  if (math_CompareThisOnly(p, flags) &&
01513   data_GetChildrenCount() >= p.data_GetChildrenCount()) {
01514 
01515   
01516   
01517   
01518   
01519   
01520   for (int i=0,max=p.data_GetChildrenCount(); i<max; i++)
01521    if (!data_GetConstChild(i).math_Compare(p.data_GetConstChild(i), flags))
01522     return math_RecursiveFindInChildrenOnly(n, p, flags); 
01523 
01524   
01525   
01526   
01527   
01528   
01529   if (--n == -1) {
01530 
01531    
01532    
01533    
01534    
01535    
01536    if (flags & mcFIND_PARENT)
01537     return mcEmptyElement;
01538 
01539    return mcElement(this);
01540   }
01541  }
01542 
01543  
01544  return math_RecursiveFindInChildrenOnly(n, p, flags);
01545 }
01546 
01547 int mcElementHelpers::math_GetCountOfChildrenOnly(const mcElement &p, long flags) const
01548 {
01549  int total = 0;
01550 
01551  for (int i=0,max=data_GetChildrenCount(); i<max; i++)
01552   total += data_GetConstChild(i).math_GetCountOf(p, flags);
01553 
01554  return total;
01555 }
01556 
01557 int mcElementHelpers::math_GetCountOf(const mcElement &p, long flags) const
01558 {
01559  int total = 0;
01560 
01561  if (math_CompareThisOnly(p, flags) &&
01562   data_GetChildrenCount() >= p.data_GetChildrenCount()) {     
01563 
01564   for (int i=0,max=p.data_GetChildrenCount(); i<max; i++)
01565    if (!data_GetConstChild(i).math_Compare(p.data_GetConstChild(i), flags))
01566     return math_GetCountOfChildrenOnly(p, flags);
01567 
01568   total++;
01569  }
01570 
01571  return total+math_GetCountOfChildrenOnly(p, flags);
01572 }
01573 
01574 int mcElementHelpers::math_GetCountOf(const mcSymbolProperties *p, long flags) const
01575 {
01576  mcSymbol safe(p->data_GetSafeLinkedSym());
01577  mcASSERT(safe.data_isOk(), wxT("Invalid safe symbol ?"));
01578 
01579  return math_GetCountOf(safe, flags);
01580 }
01581 
01582 int mcElementHelpers::math_GetCountOf(const mcSymbolArray *p, long flags) const
01583 {
01584  int total = 0;
01585 
01586  
01587  for (int i=0; i<p->data_GetCount(); i++)
01588   total += math_GetCountOf(p->data_GetSymbol(i), flags);
01589 
01590  return total;
01591 }
01592 
01593 int mcElementHelpers::math_GetCountOfSymbolsType(const mcSymbolArray *p, long flags) const
01594 {
01595  int total = 0;
01596 
01597  
01598  
01599  
01600  
01601  for (int i=0; i<p->data_GetCount(); i++)
01602   total += (int)math_ContainsSymbol(p->data_GetSymbol(i));
01603 
01604  return total;
01605 }
01606 
01607 int mcElementHelpers::math_Replace(const mcElement &tofind, int n, long flags,
01608        const mcElement &replacement, bool addchildren)
01609 {
01610  mcMATHLOG(wxT("mcElementHelpers::math_Replace [%s] - going to replace [%s] with [%s]"),
01611     mcTXTTHIS, mcTXT(tofind), mcTXT(replacement));
01612  mcElement p(mcEmptyElement);
01613  int ntotal = 0;
01614  bool onlyone = (n != -1);
01615  int occ = (onlyone ? n : 0);
01616 
01617  
01618  mcElement parent = math_Find(occ, tofind, flags | mcFIND_PARENT);
01619  if (parent == mcEmptyElement) return 0;
01620  const mcElement *currtofind = &parent;
01621 
01622  mcElement currparent(mcEmptyElement);
01623  while (currtofind) {
01624 
01625   
01626   
01627   currparent = math_Find(0, *currtofind, flags | mcFIND_PARENT);
01628   if (currparent == mcEmptyElement) break;
01629 
01630   
01631   
01632   if (currparent.data_GetRefData()->data_GetRefCount() > 2)
01633    currtofind = &currparent;
01634   else
01635    currtofind = NULL;
01636  }
01637 
01638  
01639  
01640 
01641 
01642 
01643 
01644 
01645 
01646 
01647 
01648 
01649 
01650 
01651 
01652 
01653 
01654 
01655 
01656 
01657 
01658 
01659 
01660 
01661 
01662 
01663 
01664 
01665 
01666 
01667 
01668 
01669 
01670 
01671 
01672 
01673 
01674 
01675 
01676 
01677 
01678 
01679 
01680 
01681 
01682 
01683 
01684 
01685 
01686 
01687 
01688 
01689 
01690 
01691 
01692 
01693 
01694 
01695 
01696 
01697 
01698 
01699  
01700  return ntotal;
01701 }
01702 
01703 
01704 
01705 
01706 mcMonomial mcElement::math_GetLCM(const mcElement &p) const
01707 { return hlp()->math_GetLCM(p); }
01708 
01709 mcMonomial mcElement::math_GetGCD(const mcElement &p) const
01710 { return hlp()->math_GetGCD(p); }
01711 
01712 mcMonomial mcElement::math_GetFactors() const
01713 { return hlp()->math_GetFactors(); }
01714 
01715 
01716 
01717 
01718 mcRealValue mcElementHelpers::math_EvaluateAt(const mcSymbolProperties *sym,
01719             const mcRealValue &symvalue) const
01720 {
01721  mcMATHLOG(wxT("mcElementHelpers::math_EvaluateAt [%s] - evaluating at [%s]=%s"),
01722     mcTXTTHIS, mcTXTP(sym), mcTXTV(symvalue));
01723 
01724 #if 0
01725  mcSymbol symtorep;
01726  symtorep.data_LinkWith(&sym);
01727  mcNumber replacement;
01728  replacement.math_Set(symvalue);
01729  
01730  
01731  
01732  mcMathMng *clone = this->Clone();
01733  clone.math_Replace(&symtorep, -1, &replacement, TRUE);
01734  mcRealValue res = clone.math_Evaluate();
01735  delete clone;
01736 #endif
01737 
01738  
01739 
01740 
01741 
01742 
01743 
01744 
01745 
01746 
01747 
01748 
01749 
01750 
01751 
01752 
01753 
01754 
01755 
01756 
01757 
01758 
01759 
01760 
01761 
01762 
01763 
01764 
01765 
01766  
01767  
01768  
01769  mcSymbolProperties *psym = (mcSymbolProperties *)sym;
01770 
01771  
01772  psym->m_bEvaluating = TRUE;
01773  psym->m_fValue = symvalue;
01774 
01775  
01776  mcRealValue res = math_Evaluate();
01777 
01778  
01779  psym->m_bEvaluating = FALSE;
01780  psym->m_fValue = *mcRealValue::pNAN;
01781 
01782  mcMATHLOG(wxT("mcElementHelpers::math_EvaluateAt - result is %s"), mcTXTV(res));
01783  return res;
01784 }