-/*
-TODO:
- - Non shrink-to-fit row-col behaviour.
- - Give justification styles, so can e.g. centre
- the rows & cols, distribute the available space...
- - Shrink-to-fit: should resize outer window (e.g. dialog box)
- if directly associated with this kind of window.
- - How to deal with a rowcol that stretches in one direction
- but shrinks-to-fit in other. E.g. a horizontal toolbar: the width
- stretches to fit the frame, but the height is constant
- or wraps around contents. The algorithm currently assumes
- both dimensions have the same behaviour. Could assume a constant
- height (absolute value).
- - rowcol where each row or column is aligned (length of
-   largest element determines spacing)
- - Groupbox sizer
- - Analyze aesthetic dialog boxes and implement using sizers.
- - What reuseable components can we provide? E.g. Ok/Cancel/Help
-   group of buttons.
- - use wxStaticItems for aesthetic dialogs.
-
-*/
-
-// Find margin sizes if a sizer, or zero otherwise
-int wxSizerMarginX(wxWindow *win)
-{
-       if ( win->IsKindOf(CLASSINFO(wxSizer)) )
-       {
-               wxSizer *sizer = (wxSizer *)win;
-               return sizer->GetBorderX();
-       }
-       else
-               return 0;
-}
-
-int wxSizerMarginY(wxWindow *win)
-{
-       if ( win->IsKindOf(CLASSINFO(wxSizer)) )
-       {
-               wxSizer *sizer = (wxSizer *)win;
-               return sizer->GetBorderY();
-       }
-       else
-               return 0;
-}
-
-
-wxIndividualLayoutConstraint::wxIndividualLayoutConstraint(void)
-{
-  myEdge = wxTop; relationship = wxUnconstrained; margin = 0; value = 0; percent = 0; otherEdge = wxTop;
-  done = FALSE; otherWin = NULL;
-}
-
-wxIndividualLayoutConstraint::~wxIndividualLayoutConstraint(void)
-{
-}
-
-void wxIndividualLayoutConstraint::Set(wxRelationship rel, wxWindow *otherW, wxEdge otherE, int val, int marg)
-{
-  relationship = rel; otherWin = otherW; otherEdge = otherE; value = val; margin = marg;
-}
-
-void wxIndividualLayoutConstraint::LeftOf(wxWindow *sibling, int marg)
-{ Set(wxLeftOf, sibling, wxLeft, 0, marg); }
-
-void wxIndividualLayoutConstraint::RightOf(wxWindow *sibling, int marg)
-{ Set(wxRightOf, sibling, wxRight, 0, marg); }
-
-void wxIndividualLayoutConstraint::Above(wxWindow *sibling, int marg)
-{ Set(wxAbove, sibling, wxTop, 0, marg); }
-
-void wxIndividualLayoutConstraint::Below(wxWindow *sibling, int marg)
-{ Set(wxBelow, sibling, wxBottom, 0, marg); }
-
-//
-// 'Same edge' alignment
-//
-void wxIndividualLayoutConstraint::SameAs(wxWindow *otherW, wxEdge edge, int marg)
-{ Set(wxPercentOf, otherW, edge, 0, marg); percent = 100; }
-
-// The edge is a percentage of the other window's edge
-void wxIndividualLayoutConstraint::PercentOf(wxWindow *otherW, wxEdge wh, int per)
-{ otherWin = otherW; relationship = wxPercentOf; percent = per;
-  otherEdge = wh;
-}
-
-//
-// Edge has absolute value
-//
-void wxIndividualLayoutConstraint::Absolute(int val)
-{ value = val; relationship = wxAbsolute; }
-
-// Reset constraint if it mentions otherWin
-bool wxIndividualLayoutConstraint::ResetIfWin(wxWindow *otherW)
-{
-  if (otherW == otherWin)
-  {
-    myEdge = wxTop; relationship = wxAsIs; margin = 0; value = 0; percent = 0; otherEdge = wxTop;
-    otherWin = NULL;
-    return TRUE;
-  }
-  else
-    return FALSE;
-}
-
-// Try to satisfy constraint
-bool wxIndividualLayoutConstraint::SatisfyConstraint(wxLayoutConstraints *constraints, wxWindow *win)
-{
-  if (relationship == wxAbsolute)
-  {
-    done = TRUE;
-    return TRUE;
-  }
-  
-  switch (myEdge)
-  {
-    case wxLeft:
-    {
-      switch (relationship)
-      {
-        case wxLeftOf:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxRightOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the left-hand edge position if we know
-          // the right-hand edge and we know the width; OR if we know the centre and the width.
-          if (constraints->right.GetDone() && constraints->width.GetDone())
-          {
-            value = (constraints->right.GetValue() - constraints->width.GetValue() + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreX.GetDone() && constraints->width.GetDone())
-          {
-            value = (int)(constraints->centreX.GetValue() - (constraints->width.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          int y;
-          win->GetPosition(&value, &y);
-          done = TRUE;
-          return TRUE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxRight:
-    {
-      switch (relationship)
-      {
-        case wxLeftOf:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxRightOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the right-hand edge position if we know
-          // the left-hand edge and we know the width, OR if we know the
-          // centre edge and the width.
-          if (constraints->left.GetDone() && constraints->width.GetDone())
-          {
-            value = (constraints->left.GetValue() + constraints->width.GetValue() - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreX.GetDone() && constraints->width.GetDone())
-          {
-            value = (int)(constraints->centreX.GetValue() + (constraints->width.GetValue()/2) - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          int x, y;
-          int w, h;
-          win->GetSize(&w, &h);
-          win->GetPosition(&x, &y);
-          value = x + w;
-          done = TRUE;
-          return TRUE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxTop:
-    {
-      switch (relationship)
-      {
-        case wxAbove:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxBelow:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the top edge position if we know
-          // the bottom edge and we know the height; OR if we know the centre
-          // edge and the height.
-          if (constraints->bottom.GetDone() && constraints->height.GetDone())
-          {
-            value = (constraints->bottom.GetValue() - constraints->height.GetValue() + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreY.GetDone() && constraints->height.GetDone())
-          {
-            value = (constraints->centreY.GetValue() - (constraints->height.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          int x;
-          win->GetPosition(&x, &value);
-          done = TRUE;
-          return TRUE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxBottom:
-    {
-      switch (relationship)
-      {
-        case wxAbove:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxBelow:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the bottom edge position if we know
-          // the top edge and we know the height; OR if we know the
-          // centre edge and the height.
-          if (constraints->top.GetDone() && constraints->height.GetDone())
-          {
-            value = (constraints->top.GetValue() + constraints->height.GetValue() - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreY.GetDone() && constraints->height.GetDone())
-          {
-            value = (constraints->centreY.GetValue() + (constraints->height.GetValue()/2) - margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          int x, y;
-          int w, h;
-          win->GetSize(&w, &h);
-          win->GetPosition(&x, &y);
-          value = h + y;
-          done = TRUE;
-          return TRUE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxCentreX:
-    {
-      switch (relationship)
-      {
-        case wxLeftOf:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxRightOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the centre position if we know
-          // the left-hand edge and we know the width, OR
-          // the right-hand edge and the width
-          if (constraints->left.GetDone() && constraints->width.GetDone())
-          {
-            value = (int)(constraints->left.GetValue() + (constraints->width.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->right.GetDone() && constraints->width.GetDone())
-          {
-            value = (int)(constraints->left.GetValue() - (constraints->width.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxCentreY:
-    {
-      switch (relationship)
-      {
-        case wxAbove:
-        {
-          // We can know this edge if: otherWin is win's parent,
-          // or otherWin has a satisfied constraint, or
-          // otherWin has no constraint.
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos - margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxBelow:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = edgePos + margin;
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the centre position if we know
-          // the top edge and we know the height, OR
-          // the bottom edge and the height.
-          if (constraints->bottom.GetDone() && constraints->height.GetDone())
-          {
-            value = (int)(constraints->bottom.GetValue() - (constraints->height.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->top.GetDone() && constraints->height.GetDone())
-          {
-            value = (int)(constraints->top.GetValue() + (constraints->height.GetValue()/2) + margin);
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxWidth:
-    {
-      switch (relationship)
-      {
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01));
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          if (win)
-          {
-            int h;
-            win->GetSize(&value, &h);
-            done = TRUE;
-            return TRUE;
-          }
-          else return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the width if we know the left edge and the right edge, OR
-          // if we know the left edge and the centre, OR
-          // if we know the right edge and the centre
-          if (constraints->left.GetDone() && constraints->right.GetDone())
-          {
-            value = constraints->right.GetValue() - constraints->left.GetValue();
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreX.GetDone() && constraints->left.GetDone())
-          {
-            value = (int)(2*(constraints->centreX.GetValue() - constraints->left.GetValue()));
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->centreX.GetDone() && constraints->right.GetDone())
-          {
-            value = (int)(2*(constraints->right.GetValue() - constraints->centreX.GetValue()));
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    case wxHeight:
-    {
-      switch (relationship)
-      {
-        case wxPercentOf:
-        {
-          int edgePos = GetEdge(otherEdge, win, otherWin);
-          if (edgePos != -1)
-          {
-            value = (int)(edgePos*(((float)percent)*0.01));
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        case wxAsIs:
-        {
-          if (win)
-          {
-            int w;
-            win->GetSize(&w, &value);
-            done = TRUE;
-            return TRUE;
-          }
-          else return FALSE;
-        }
-        case wxUnconstrained:
-        {
-          // We know the height if we know the top edge and the bottom edge, OR
-          // if we know the top edge and the centre, OR
-          // if we know the bottom edge and the centre
-          if (constraints->top.GetDone() && constraints->bottom.GetDone())
-          {
-            value = constraints->bottom.GetValue() - constraints->top.GetValue();
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->top.GetDone() && constraints->centreY.GetDone())
-          {
-            value = (int)(2*(constraints->centreY.GetValue() - constraints->top.GetValue()));
-            done = TRUE;
-            return TRUE;
-          }
-          else if (constraints->bottom.GetDone() && constraints->centreY.GetDone())
-          {
-            value = (int)(2*(constraints->bottom.GetValue() - constraints->centreY.GetValue()));
-            done = TRUE;
-            return TRUE;
-          }
-          else
-            return FALSE;
-        }
-        default:
-          break;
-      }
-      break;
-    }
-    default:
-      break;
-  }
-  return FALSE;
-}
-
-// Get the value of this edge or dimension, or if this
-// is not determinable, -1.
-int wxIndividualLayoutConstraint::GetEdge(wxEdge which, wxWindow *thisWin, wxWindow *other)
-{
-  // If the edge or dimension belongs to the parent, then we
-  // know the dimension is obtainable immediately.
-  // E.g. a wxExpandSizer may contain a button (but the button's
-  // true parent is a panel, not the sizer)
-  if (other->GetChildren()->Member(thisWin))
-  {
-    switch (which)
-    {
-      case wxLeft:
-         {
-               return wxSizerMarginX(other);
-         }
-      case wxTop:
-      {
-        return wxSizerMarginY(other);
-      }
-      case wxRight:
-         {
-        int w, h;
-        other->GetClientSizeConstraint(&w, &h);
-        return w - wxSizerMarginX(other);
-         }
-      case wxBottom:
-         {
-        int w, h;
-        other->GetClientSizeConstraint(&w, &h);
-        return h - wxSizerMarginY(other);
-         }
-      case wxWidth:
-         {
-        int w, h;
-        other->GetClientSizeConstraint(&w, &h);
-        return w - 2*wxSizerMarginX(other);
-         }
-      case wxHeight:
-      {
-        int w, h;
-        other->GetClientSizeConstraint(&w, &h);
-        return h - 2*wxSizerMarginY(other);
-      }
-      case wxCentreX:
-      case wxCentreY:
-      {
-        int w, h;
-        other->GetClientSizeConstraint(&w, &h);
-        if (which == wxCentreX)
-          return (int)(w/2);
-        else
-          return (int)(h/2);
-      }
-      default:
-        return -1;
-    }
-  }
-  switch (which)
-  {
-    case wxLeft:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->left.GetDone())
-          return constr->left.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y;
-        other->GetPosition(&x, &y);
-        return x;
-      }
-    }
-    case wxTop:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->top.GetDone())
-          return constr->top.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y;
-        other->GetPosition(&x, &y);
-        return y;
-      }
-    }
-    case wxRight:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->right.GetDone())
-          return constr->right.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y, w, h;
-        other->GetPosition(&x, &y);
-        other->GetSize(&w, &h);
-        return (int)(x + w);
-      }
-    }
-    case wxBottom:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->bottom.GetDone())
-          return constr->bottom.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y, w, h;
-        other->GetPosition(&x, &y);
-        other->GetSize(&w, &h);
-        return (int)(y + h);
-      }
-    }
-    case wxWidth:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->width.GetDone())
-          return constr->width.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int w, h;
-        other->GetSize(&w, &h);
-        return w;
-      }
-    }
-    case wxHeight:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->height.GetDone())
-          return constr->height.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int w, h;
-        other->GetSize(&w, &h);
-        return h;
-      }
-    }
-    case wxCentreX:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->centreX.GetDone())
-          return constr->centreX.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y, w, h;
-        other->GetPosition(&x, &y);
-        other->GetSize(&w, &h);
-        return (int)(x + (w/2));
-      }
-    }
-    case wxCentreY:
-    {
-      wxLayoutConstraints *constr = other->GetConstraints();
-      // If no constraints, it means the window is not dependent
-      // on anything, and therefore we know its value immediately
-      if (constr)
-      {
-        if (constr->centreY.GetDone())
-          return constr->centreY.GetValue();
-        else
-          return -1;
-      }
-      else
-      {
-        int x, y, w, h;
-        other->GetPosition(&x, &y);
-        other->GetSize(&w, &h);
-        return (int)(y + (h/2));
-      }
-    }
-    default:
-      break;
-  }
-  return -1;
-}