/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "editor.hxx"

#undef NDEBUG

/* 
#include <stdio.h>
#include <string.h>
*/

#include <cassert>
#include <cstdio>
#include <cstring>
#include <list>
#include <vector>

#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/XLayoutConstrains.hpp>
#include <com/sun/star/awt/XLayoutContainer.hpp>
#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <toolkit/helper/property.hxx>
#include <vcl/lstbox.h>

using namespace layout::css;

using rtl::OUString;

// FIXME:
//#define FILEDLG

#include <layout/core/helper.hxx>
#include <layout/core/root.hxx>
#include <layout/core/helper.hxx>

// TODO: automatically generated
struct WidgetSpec {
    const char *pLabel, *pName, *pIconName;
    bool bIsContainer; };
static const WidgetSpec WIDGETS_SPECS[] = {
    { "Label",         "fixedtext"   , "sc_label.png",        false },
    { "Button",        "pushbutton"  , "sc_pushbutton.png",   false },
    { "Radio Button",  "radiobutton" , "sc_radiobutton.png",  false },
    { "Check Box",     "checkbox"    , "sc_checkbox.png",     false },
    { "Line Edit",     "edit"        , "sc_edit.png",         false },
    { "Numeric Field", "numericfield", "sc_numericfield.png", false },
    { "List Box                  ", "listbox"     , NULL,                  false },
    // containers
    { "Hor Box",       "hbox"        , NULL,                  true  },
    { "Ver Box",       "vbox"        , NULL,                  true  },
    { "Table",         "table"       , NULL,                  true  },
    { "Alignment",     "align"       , NULL,                  true  },
    { "Tab Control",   "tabcontrol"  , NULL,                  true  },
    { "Hor Splitter",  "hsplitter"   , NULL,                  true  },
    { "Ver Splitter",  "vsplitter"   , NULL,                  true  },
    { "Scroller",      "scroller"    , NULL,                  true  },
};
const int WIDGETS_SPECS_LEN = sizeof (WIDGETS_SPECS) / sizeof (WidgetSpec);

using namespace layout;
using namespace layoutimpl;
namespace css = ::com::sun::star;

static rtl::OUString anyToString (uno::Any value)
{
    try
    {
        switch (value.getValueTypeClass()) {
            case uno::TypeClass_STRING:
                return value.get<rtl::OUString>();
            case uno::TypeClass_CONSTANT:
                return rtl::OUString::valueOf (value.get<sal_Int32>());
            case uno::TypeClass_LONG:
                return rtl::OUString::valueOf (value.get<sal_Int64>());
            case uno::TypeClass_SHORT:
                // FIXME: seems broken
                return rtl::OUString::valueOf ((sal_Int32) value.get<short>());

            case uno::TypeClass_FLOAT:
                return rtl::OUString::valueOf (value.get<float>());
            case uno::TypeClass_DOUBLE:
                return rtl::OUString::valueOf (value.get<double>());

            case uno::TypeClass_BOOLEAN:
            {
                bool val = value.get<sal_Bool>();
                return rtl::OUString( val ? "1" : "0", 1, RTL_TEXTENCODING_ASCII_US );
/*                if ( val )
                  return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
                  else
                  return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );*/
            }
            default:
                break;
        }
    }
    catch(...) {}
    return rtl::OUString();
}

static inline long anyToNatural (uno::Any value)
{ return sal::static_int_cast<long>(anyToString( value ).toInt64()); }
static inline double anyToDecimal (uno::Any value)
{ return anyToString( value ).toDouble(); }

/* XLayoutContainer/XLayoutConstrains are a bit of a hasle to work with.
   Let's wrap them. */
class Widget : public layoutimpl::LayoutWidget
{
    friend class EditorRoot;

    Widget *mpParent;
    std::vector< Widget *> maChildren;
    bool mbForeign;

    rtl::OUString mrId;
    rtl::OUString mrLabel, mrUnoName;

// TODO: store original properties. And some property handling methods.
    long mnOriAttrbs;
    layoutimpl::PropList maOriProps, maOriChildProps;

public:

    // to be used to wrap the root
    Widget( uno::Reference< awt::XLayoutConstrains > xImport, const char *label )
        : mpParent( 0 ), mbForeign( true )
    {
        mxWidget = xImport;
        mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );

        mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8  );

#if 0  /* obsolete */
        // FIXME: this code is meant to import a XML file. Just use the importer,
        // then pass the root widget. But information like the ID string is lost.
        // So, this needs to be more closely tight to the importer.
        uno::Sequence< uno::Reference< awt::XLayoutConstrains > > aChildren;
        for ( int i = 0; i < aChildren.getLength(); i++ )
        {
            Widget *pChild = new Widget( aChildren[ i ], "---" );
            maChildren.push_back( pChild );
            pChild->mpParent = this;
        }
#endif
    }

    Widget( rtl::OUString id, uno::Reference< awt::XToolkit > xToolkit,
            uno::Reference< awt::XLayoutContainer > xParent,
            rtl::OUString unoName, long nAttrbs )
        : mpParent( 0 ), mbForeign( false ), mrId( id ),
          mnOriAttrbs( nAttrbs )
    {
        while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() )
        {
            uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY );
            OSL_ASSERT( xContainer.is() );
            xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY );
        }
        
        mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, nAttrbs );
        OSL_ASSERT( mxWidget.is() );
        mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
        
        mrLabel = mrUnoName = unoName;
        // try to get a nicer label for the widget
        for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ )
            if ( unoName.equalsAscii( WIDGETS_SPECS[ i ].pName ) )
            {
                const char *label = WIDGETS_SPECS[ i ].pLabel;
                mrLabel = rtl::OUString( label, strlen( label ), RTL_TEXTENCODING_UTF8  );
                break;
            }
        
        // set default Text property
        // TODO: disable editing of text fields, check boxes selected, etc...
#if 0
        uno::Reference< awt::XVclWindowPeer> xVclPeer( mxWidget, uno::UNO_QUERY )
            if ( xVclPeer.is() ) // XVclWindowPeer ignores missing / incorrect properties 

//FIXME: it looks odd on widgets like NumericField seeing text which is deleted
// when you interact with it... We can avoid it for those widgets, by doing a getProp
// of "Text" and check if it is empty or not.
            
                xVclPeer->setProperty( rtl::OUString::createFromAscii( "Text" ),
                                       uno::makeAny( rtl::OUString::createFromAscii( "new widget" ) ) );
#endif
        
        // store original properties
        {
            PropertyIterator it( this, WINDOW_PROPERTY );
            while ( it.hasNext() )
            {
                beans::Property prop = it.next();
                rtl::OUString name( prop.Name );
                rtl::OUString value( getProperty( name, WINDOW_PROPERTY ) );
#if DEBUG_PRINT
                fprintf(stderr, "original property: %s = %s\n", OUSTRING_CSTR(name), OUSTRING_CSTR(value));
#endif
                std::pair< rtl::OUString, rtl::OUString > pair( name, value );
                maOriProps.push_back( pair );
            }
        }

    }

    ~Widget()
    {
        for ( std::vector< Widget *>::const_iterator it = maChildren.begin();
             it != maChildren.end(); it++ )
            delete *it;
        if ( !mbForeign )
        {
            uno::Reference< lang::XComponent > xComp( mxWidget, uno::UNO_QUERY );
            if ( xComp.is() )
                // some widgets, like our containers, don't implement this interface...
                xComp->dispose();
        }
    }

    uno::Reference< awt::XLayoutConstrains > impl()
    {
        return mxWidget;
    }

    // LayoutWidget
    virtual bool addChild( LayoutWidget *pChild )
    {
        return addChild( static_cast< Widget * >( pChild ) );
    }

    virtual void setProperties( const PropList &rProps )
    {
//        maOriProps = rProps;
        LayoutWidget::setProperties( rProps );
    }

    virtual void setChildProperties( LayoutWidget *pChild, const PropList &rProps )
    {
        maOriChildProps = rProps;        
        LayoutWidget::setChildProperties( pChild, rProps );
    }

    // tree travel
    Widget *up()
    {
        return mpParent;
    }

    Widget *down()
    {
        if ( maChildren.empty() )
            return NULL;
        return maChildren.front();
    }

    Widget *next()
    {
        if ( mpParent )
        {
            int pos = mpParent->getChildPos( this );
            return mpParent->getChild( pos+1 );
        }
        return NULL;
    }

    Widget *prev()
    {
        if ( mpParent )
        {
            int pos = mpParent->getChildPos( this );
            return mpParent->getChild( pos-1 );
        }
        return NULL;
    }

    // handle
    bool addChild( Widget *pChild, int pos = 0xffff )
    {
        if ( !mxContainer.is() )
            return false;

        uno::Sequence< uno::Reference < awt::XLayoutConstrains > > aChildren;
        aChildren = mxContainer->getChildren();
        int nChildrenLen = aChildren.getLength();

        // ugly, but let's check if the container is next to full...
        try {
            mxContainer->addChild( pChild->mxWidget );
        }
        catch( awt::MaxChildrenException ex ) {
            return false;
        }

        if ( pos < nChildrenLen )
        {  // if its on the middle, we need to make space for it
            mxContainer->removeChild( pChild->mxWidget );
            for ( int i = pos; i < nChildrenLen; i++ )
                mxContainer->removeChild( aChildren[ i ] );
            mxContainer->addChild( pChild->mxWidget );
            for ( int i = pos; i < nChildrenLen; i++ )
                mxContainer->addChild( aChildren[ i ] );
            maChildren.insert( maChildren.begin()+pos, pChild );
        }
        else
            maChildren.push_back( pChild );

        OSL_ASSERT( pChild->mpParent == NULL );
        pChild->mpParent = this;

        // store container props
        {
            pChild->maOriChildProps.clear();
            PropertyIterator it( pChild, CONTAINER_PROPERTY );
            while ( it.hasNext() )
            {
                beans::Property prop = it.next();
                rtl::OUString name( prop.Name );
		try {
			rtl::OUString value( pChild->getProperty( name, CONTAINER_PROPERTY ) );
			std::pair< rtl::OUString, rtl::OUString > pair( name, value );
			pChild->maOriChildProps.push_back( pair );
		} catch ( beans::UnknownPropertyException &rEx ) {
			fprintf (stderr, "ERROR: widget reports that it has a property it cannot return: '%s' this normally means that someone screwed up their PROPERTY_SET_INFO macro usage.\n",
				 rtl::OUStringToOString (rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
		}
            }
        }

        return true;
    }

    bool removeChild( Widget *pChild )
    {
        if ( !mxContainer.is() || pChild->mpParent != this )
            return false;

        mxContainer->removeChild( pChild->mxWidget );

        unsigned int pos = getChildPos( pChild );
        if ( pos < maChildren.size() )
            maChildren.erase( maChildren.begin()+pos );
        pChild->mpParent = NULL;

        return true;
    }

    bool swapWithChild( Widget *pChild )
    {
        if ( !pChild->isContainer() )
            return false;

        // remove all child's childrens, and try to add them here
        removeChild( pChild );

        // keep a copy for failure
        std::vector< Widget *> aChildren = maChildren;
        std::vector< Widget *> aChildChildren = pChild->maChildren;

        for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin();
              it != aChildChildren.end(); it++ )
            pChild->removeChild( *it );

        for ( std::vector< Widget *>::const_iterator it = aChildChildren.begin();
              it != aChildChildren.end(); it++ )
            if ( !addChild( *it ) )
            {    // failure
                for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin();
                      jt != it; jt++ )
                    removeChild( *jt );
                for ( std::vector< Widget *>::const_iterator jt = aChildChildren.begin();
                      jt != aChildChildren.end(); jt++ )
                    pChild->addChild( *jt );
                return false;
            }

        Widget *pParent = up();

        if ( pParent )
        {
            pParent->removeChild( this );
            pParent->addChild( pChild );
        }
        pChild->addChild( this );
        return true;
    }

    unsigned int getChildPos( Widget *pChild )
    {
        int i = 0;
        for ( std::vector< Widget *>::const_iterator it = maChildren.begin();
              it != maChildren.end(); it++, i++ )
            if ( *it == pChild )
                break;
        return i;
    }

    Widget *getChild( int pos )
    {
        if ( pos >= 0 && pos < (signed) maChildren.size() )
            return *(maChildren.begin() + pos);
        return NULL;
    }

    bool isContainer()
    { return mxContainer.is(); }
    unsigned int getChildrenLen()
    { return maChildren.size(); }

    rtl::OUString getLabel() const
    { return mrLabel; }
    rtl::OUString getUnoName() const
    { return mrUnoName; }

    int getDepth()
    {
        int depth = 0;
        for ( Widget *pWidget = mpParent; pWidget; pWidget = pWidget->mpParent )
            depth++;
        return depth;
    }

    enum PropertyKind {
        WINDOW_PROPERTY, CONTAINER_PROPERTY, WINBITS_PROPERTY
    };

    static rtl::OUString findProperty( const PropList &props, rtl::OUString propName )
    {
        for ( PropList::const_iterator it = props.begin(); it != props.end(); it++ )
            if ( it->first.equalsIgnoreAsciiCase( propName ) )
                return it->second;
#if DEBUG_PRINT
        fprintf(stderr, "Serious error: property '%s' not found\n", OUSTRING_CSTR(propName));
#endif
        return rtl::OUString();
    }

    rtl::OUString getOriginalProperty( rtl::OUString rPropName, PropertyKind rKind )
    {
        rtl::OUString rValue;
        switch ( rKind ) {
            case WINDOW_PROPERTY:
                rValue = findProperty( maOriProps, rPropName );
                break;
            case CONTAINER_PROPERTY:
                rValue = findProperty( maOriChildProps, rPropName );
                break;
            case WINBITS_PROPERTY:
                // TODO
                break;
        }

        return rValue;
    }

    rtl::OUString getProperty( rtl::OUString rPropName, PropertyKind rKind )
    {
        rtl::OUString rValue;
        switch ( rKind ) {
            case WINDOW_PROPERTY:
                rValue = anyToString( layoutimpl::prophlp::getProperty( mxWidget, rPropName ) );
                break;
            case CONTAINER_PROPERTY:
                if ( mpParent )
                    rValue = anyToString( layoutimpl::prophlp::getProperty(
                                              mpParent->mxContainer->getChildProperties( mxWidget ), rPropName ) );
                break;
            case WINBITS_PROPERTY:
                // TODO
                break;
        }

        return rValue;
    }

    bool isPropertyTouched( rtl::OUString propName, PropertyKind rKind )
    {
        rtl::OUString oriValue = getOriginalProperty( propName, rKind );
        rtl::OUString newValue = getProperty( propName, rKind );
        bool isTouched = oriValue != newValue;
#if DEBUG_PRINT
        fprintf(stderr, "is property '%s' touched? %s  (%s vs %s)\n", OUSTRING_CSTR(propName), isTouched ? "yes" : "no", OUSTRING_CSTR(oriValue), OUSTRING_CSTR(newValue));
#endif
        return isTouched;
    }

    using LayoutWidget::setProperty;
    
    void setProperty( rtl::OUString rPropName, PropertyKind rKind, uno::Any rValue )
    {
        switch ( rKind ) {
            case WINDOW_PROPERTY:
                layoutimpl::prophlp::setProperty( mxWidget, rPropName, rValue );
                break;
            case CONTAINER_PROPERTY:
                if ( mpParent )
                    layoutimpl::prophlp::setProperty(
                        mpParent->mxContainer->getChildProperties( mxWidget ), rPropName, rValue );
                break;
            case WINBITS_PROPERTY:
                // TODO
                break;
        }
    }

    struct PropertyIterator {
        friend class Widget;
        PropertyKind mrKind;
        uno::Sequence< beans::Property > maProps;
        int nPropIt;

        PropertyIterator( Widget *pWidget, PropertyKind rKind )
            : mrKind( rKind ), nPropIt( 0 )
        {
            switch ( rKind )
            {
                case WINDOW_PROPERTY:
                    if ( layoutimpl::prophlp::canHandleProps( pWidget->mxWidget ) )
                    {
                        uno::Reference< beans::XPropertySetInfo > xInfo
                            = layoutimpl::prophlp::queryPropertyInfo( pWidget->mxWidget );
                        if ( !xInfo.is() )
                            return;

                        maProps = xInfo->getProperties();
                    }
                    break;
                case CONTAINER_PROPERTY:
                    if ( pWidget->mpParent )
                    {
                        uno::Reference< beans::XPropertySet >xParentSet(
                            pWidget->mpParent->mxContainer->getChildProperties( pWidget->mxWidget ) );
                        if ( xParentSet.is())
                        {
                            uno::Reference< beans::XPropertySetInfo > xInfo( xParentSet->getPropertySetInfo() );
                            if ( xInfo.is() )
                                maProps = xInfo->getProperties();
                        }
                    }
                    break;
                case WINBITS_PROPERTY:
                    // TODO
                    break;
            }
        }

        bool hasNext()
        {
            return nPropIt < maProps.getLength();
        }

        beans::Property next()
        {
/*            rtl::OUString propName, propValue;
              propName = maProps[ nPropIt ];
              propValue = getProperty( propName, mrKind, false);
              nPropIt++;
              return std::pair< rtl::OUString, rtl::OUString > propPair( propName, propValue );*/
            return maProps[ nPropIt++ ];
        }
    };
};

class EditorRoot : public layoutimpl::LayoutRoot {
    Widget *mpParent;

public:
    EditorRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
                Widget *pParent )
        : layoutimpl::LayoutRoot( xFactory ), mpParent( pParent )
    {
    }

    // generation
    virtual layoutimpl::LayoutWidget *create( rtl::OUString id, const rtl::OUString unoName,
                                              long attrbs, uno::Reference< awt::XLayoutContainer > xParent )
    {
        if ( unoName.compareToAscii( "dialog" ) == 0 )
            return mpParent;

        // TODO: go through specs to map unoName to a more human-readable label
        Widget *pWidget = new Widget( id, mxToolkit, xParent, unoName, attrbs );
        if ( !mxWindow.is() )
            mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY );

        if ( pWidget->mxContainer.is() )
            pWidget->mxContainer->setLayoutUnit( mpParent->mxContainer->getLayoutUnit() );

        return pWidget;
    }
};

/* Working with the layout in 1D, as if it was a flat list. */
namespace FlatLayout
{
Widget *next( Widget *pWidget )
{
    Widget *pNext;
    pNext = pWidget->down();
    if ( pNext ) return pNext;
    pNext = pWidget->next();
    if ( pNext ) return pNext;
    for ( Widget *pUp = pWidget->up(); pUp != NULL; pUp = pUp->up() )
        if ( (pNext = pUp->next()) != NULL )
            return pNext;
    return NULL;
}

/*
  Widget *prev( Widget *pWidget )
  {
  Widget *pPrev;
  pPrev = pWidget->prev();
  if ( !pPrev )
  return pWidget->up();

  Widget *pBottom = pPrev->down();
  if ( pBottom )
  {
  while ( pBottom->down() || pBottom->next() )
  {
  for ( Widget *pNext = pBottom->next(); pNext; pNext = pNext->next() )
  pBottom = pNext;
  Widget *pDown = pBottom->down();
  if ( pDown )
  pBottom = pDown;
  }
  return pBottom;
  }
  return pPrev;
  }
*/

bool moveWidget( Widget *pWidget, bool up /*or down*/ )
{
    // Keep child parent&pos for in case of failure
    Widget *pOriContainer = pWidget->up();
    unsigned int oriChildPos = pOriContainer->getChildPos( pWidget );

    // Get parent&sibling before removing it, since relations get cut
    Widget *pSibling = up ? pWidget->prev() : pWidget->next();
    Widget *pContainer = pWidget->up();
    if ( !pContainer )
        return false;

    // try to swap with parent or child
    // We need to allow for this at least for the root node...
    if ( !pSibling )
    {
        if ( up )
        {
            if ( pContainer->swapWithChild( pWidget ) )
                return true;
        }
        else
        {
// TODO: this is a nice feature, but we probably want to do it explicitely...
#if 0
            if ( pWidget->down() && pWidget->swapWithChild( pWidget->down() ) )
                return true;
#endif
        }
    }

    pContainer->removeChild( pWidget );

    // if has up sibling -- append to it, else swap with it
    if ( pSibling )
    {
        if ( pSibling->addChild( pWidget, up ? 0xffff : 0 ) )
            return true;

        unsigned int childPos = pContainer->getChildPos( pSibling );
        if ( pContainer->addChild( pWidget, childPos + (up ? 0 : 1) ) )
            return true;  // should always be succesful
    }
    // go through parents -- try to get prepended to them
    else
    {
        for ( ; pContainer && pContainer->up(); pContainer = pContainer->up() )
        {
            unsigned int childPos = pContainer->up()->getChildPos( pContainer );
            if ( pContainer->up()->addChild( pWidget, childPos + (up ? 0 : 1) ) )
                return true;
        }
    }

    // failed -- try to get it to its old position
    if ( !pOriContainer->addChild( pWidget, oriChildPos ) )
    {
        // a parent should never reject a child back. but if it ever
        // happens, just kill it, we don't run an orphanate here ;P
        delete pWidget;
        return true;
    }
    return false;
}

// NOTE: root is considered to be number -1
Widget *get( Widget *pRoot, int nb )
{
    Widget *it;
    for ( it = pRoot; it != NULL && nb >= 0; it = next( it ) )
        nb--;
    return it;
}

int get( Widget *pRoot, Widget *pWidget )
{
    int nRet = -1;
    Widget *it;
    for ( it = pRoot; it != NULL && it != pWidget; it = next( it ) )
        nRet++;
    return nRet;
}
}

//** PropertiesList widget

class PropertiesList : public layout::Table
{
    class PropertyEntry
    {
        friend class PropertiesList;

        /* wrapper between the widget and Any */
        struct AnyWidget
        {
            DECL_LINK( ApplyPropertyHdl, layout::Window* );
            DECL_LINK( FlagToggledHdl, layout::CheckBox* );

            AnyWidget( Widget *pWidget, rtl::OUString aPropName, Widget::PropertyKind aPropKind )
                : mpWidget( pWidget ), maPropName( aPropName ), maPropKind( aPropKind )
            {
                mpFlag = 0;
                mbBlockFlagCallback = false;
                bFirstGet = true;
            }

            virtual ~AnyWidget()
            {
#if DEBUG_PRINT
                fprintf(stderr, "~AnyWidget\n");
#endif
            }

            void save( uno::Any aValue )
            {
                mpWidget->setProperty( maPropName, maPropKind, aValue );
                checkProperty();
            }

            void checkProperty()
            {
                bool flag = mpWidget->isPropertyTouched( maPropName, maPropKind );
                
                if ( mpFlag && mpFlag->IsChecked() != (BOOL)flag )
                {
                    CheckFlag( flag, true );
                }
            }

            void CheckFlag( bool bValue, bool bBlockCallback )
            {
                if ( bBlockCallback )
                    mbBlockFlagCallback = true;
                mpFlag->Check( bValue );
                mbBlockFlagCallback = false;
            }

            bool bFirstGet;  // HACK
            rtl::OUString getValue()
            {
//                return mpWidget->getOriProperty( maPropName );
                rtl::OUString value;
                if ( bFirstGet )    // king of ugliness
                    value = mpWidget->getProperty( maPropName, maPropKind );
                else
                    value = mpWidget->getOriginalProperty( maPropName, maPropKind );
                bFirstGet = false;
                return value;
            }

            // FIXME: wrapper should have a base class for this...
            virtual layout::Window *getWindow() = 0;
            virtual layout::Container *getContainer() { return NULL; }

            virtual void load() = 0;
            virtual void store() = 0;

            Widget *mpWidget;
            rtl::OUString maPropName;
            Widget::PropertyKind maPropKind;
            layout::CheckBox *mpFlag;
            bool mbBlockFlagCallback;
        };

        struct AnyEdit : public AnyWidget, layout::HBox
        {
            layout::Edit *mpEdit;
            bool mbMultiLine;
            layout::PushButton *mpExpand;
            DECL_LINK( ExpandEditHdl, layout::PushButton* );

            // so we can create widgets (like transforming the Edit into a
            // MultiLineEdit)
            layout::Window *mpWinParent;

            AnyEdit( Widget *pWidget, rtl::OUString aPropName,
                     Widget::PropertyKind aPropKind, layout::Window *pWinParent )
                : AnyWidget( pWidget, aPropName, aPropKind ), layout::HBox( 0, false ), mpWinParent( pWinParent )
            {
                mpEdit = NULL;
                mpExpand = new layout::PushButton( pWinParent, WB_TOGGLE );
                mpExpand->SetToggleHdl( LINK( this, AnyEdit, ExpandEditHdl ) );
                setAsMultiLine( false );

                load();
            }

            virtual ~AnyEdit()
            {
                delete mpEdit;
                delete mpExpand;
            }

            virtual layout::Window *getWindow()
            { return NULL; }
            virtual layout::Container *getContainer()
            { return this; }

            void setAsMultiLine( bool bMultiLine )
            {
                Clear();
                XubString text;
                if ( mpEdit )
                {
                    text = mpEdit->GetText();
                    printf("Remove mpEdit and expand\n");
                    Remove( mpEdit );
                    Remove( mpExpand );
                    delete mpEdit;
                }

                if ( bMultiLine )
                {
                    mpEdit = new layout::Edit( mpWinParent, WB_BORDER );
                    mpExpand->SetText( String::CreateFromAscii( "-" ) );
                }
                else
                {
                    mpEdit = new layout::Edit( mpWinParent, WB_BORDER );
                    mpExpand->SetText( String::CreateFromAscii( "+" ) );
                }

                mpEdit->SetText( text );
                mpEdit->SetModifyHdl( LINK( this, AnyEdit, ApplyPropertyHdl ) );

                Add( mpEdit, true, true, 0 );
                Add( mpExpand, false, true, 0 );

                mbMultiLine = bMultiLine;
            }

#if 0
            // TODO: make this global... We'll likely need it for export...
            struct Translate {
                const char *ori, *dest;
            };
            static rtl::OUString stringReplace( rtl::OUString _str,
                                                Translate *trans )
            {
                const sal_Unicode *str = _str.getStr();
                rtl::OUStringBuffer buf;
                int i, j, k;
                for ( i = 0; i < _str.getLength(); i++ )
                {
                    for ( j = 0; trans[ j ].ori; j++ )
                    {
                        const char *ori = trans[ j ].ori;
                        for ( k = 0; ori[ k ] && i+k < _str.getLength(); k++ )
                            if ( ori[ k ] != str[ i+k ] )
                                break;
                        if ( !ori[ k ] )
                        {
                            // found substring
                            buf.appendAscii( trans[ j ].dest );
                            i += k;
                            continue;
                        }
                    }
                    buf.append( str[ i ] );
                }
                return buf.makeStringAndClear();
            }
#endif

            virtual void load()
            {
#if 0
                // replace end of lines by "\\n" strings
                Translate trans[] = {
                    { "\\", "\\\\" }, { "\n", "\\n" }, { 0, 0 }
                }; 
                rtl::OUString str = anyToString( getValue() );
                str = stringReplace( str, trans );
                SetText( str );
#endif
                mpEdit->SetText( getValue() );
                checkProperty();
            }

            virtual void store()
            {
#if 0
                // replace "\\n" strings by actual end of lines
                Translate trans[] = {
                    { "\\\\", "\\"  }, { "\\n", "\n" },
                    { "\\", "" }, { 0, 0 }
                }; 
                rtl::OUString str = GetText();
                str = stringReplace( str, trans );
                save( uno::makeAny( str ) );
#endif
                save( uno::makeAny( (rtl::OUString) mpEdit->GetText() ) );
            }
        };

        struct AnyInteger : public AnyWidget, NumericField
        {
            AnyInteger( Widget *pWidget, rtl::OUString aPropName,
                        Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyWidget( pWidget, aPropName, aPropKind ), NumericField( pWinParent, WB_SPIN|WB_BORDER )
            {
                load();
                SetModifyHdl( LINK( this, AnyInteger, ApplyPropertyHdl ) );
            }

            virtual Window *getWindow()
            { return this; }

            virtual void load()
            {
                OUString text = getValue();
                SetText( text.getStr() );
                checkProperty();
            }

            virtual void store()
            {
#if DEBUG_PRINT
                fprintf(stderr, "store number: %ld\n", rtl::OUString( GetText() ).toInt64());
#endif
                save( uno::makeAny( rtl::OUString( GetText() ).toInt64() ) );
            }
        };

        struct AnyFloat : public AnyInteger
        {
            AnyFloat( Widget *pWidget, rtl::OUString aPropName,
                      Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyInteger( pWidget, aPropName, aPropKind, pWinParent )
            {}

            virtual void store()
            {
                save( uno::makeAny( rtl::OUString( GetText() ).toDouble() ) );
            }
        };

        struct AnyCheckBox : public AnyWidget, layout::CheckBox
        {
            AnyCheckBox( Widget *pWidget, rtl::OUString aPropName,
                         Widget::PropertyKind aPropKind, layout::Window *pWinParent )
                : AnyWidget( pWidget, aPropName, aPropKind ), layout::CheckBox( pWinParent )
            {
                // adding some whitespaces to make the hit area larger
//                SetText( String::CreateFromAscii( "" ) );
                load();
                SetToggleHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) );
            }

            virtual ~AnyCheckBox()
            {
#if DEBUG_PRINT
                fprintf(stderr, "~AnyCheckBox\n");
#endif
            }

            virtual layout::Window *getWindow()
            { return this; }

            virtual void load()
            {
#if DEBUG_PRINT
                fprintf(stderr, "loading boolean value\n");
#endif
                Check( getValue().toInt64() != 0 );
                setLabel();
                checkProperty();
            }

            virtual void store()
            {
                save( uno::makeAny( IsChecked() ) );
                setLabel();
            }

            void setLabel()
            {
                SetText( String::CreateFromAscii( IsChecked() ? "true" : "false" ) );
            }            
        };

        struct AnyListBox : public AnyWidget, layout::ListBox
        {
            AnyListBox( Widget *pWidget, rtl::OUString aPropName,
                        Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyWidget( pWidget, aPropName, aPropKind ), layout::ListBox( pWinParent, WB_DROPDOWN )
            {
                SetSelectHdl( LINK( this, AnyWidget, ApplyPropertyHdl ) );
            }

            virtual layout::Window *getWindow()
            { return this; }

            virtual void load()
            {
                SelectEntryPos( sal::static_int_cast< USHORT >( getValue().toInt32() ) );
                checkProperty();
            }

            virtual void store()
            {
                save( uno::makeAny( (short) GetSelectEntryPos() ) );
            }
        };

        struct AnyAlign : public AnyListBox
        {
            AnyAlign( Widget *pWidget, rtl::OUString aPropName,
                      Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyListBox( pWidget, aPropName, aPropKind, pWinParent )
            {
                InsertEntry( XubString::CreateFromAscii( "Left" ) );
                InsertEntry( XubString::CreateFromAscii( "Center" ) );
                InsertEntry( XubString::CreateFromAscii( "Right" ) );
                load();
            }
        };

        /* AnyListBox and AnyComboBox different in that a ComboBox allows the user
           to add other options, operating in strings, instead of constants.
           (its more like a suggestive AnyEdit) */
        struct AnyComboBox : public AnyWidget, layout::ComboBox
        {
            AnyComboBox( Widget *pWidget, rtl::OUString aPropName,
                         Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyWidget( pWidget, aPropName, aPropKind ), layout::ComboBox( pWinParent, WB_DROPDOWN )
            {
                SetModifyHdl( LINK( this, AnyComboBox, ApplyPropertyHdl ) );
            }

            virtual layout::Window *getWindow()
            { return this; }

            virtual void load()
            {
                SetText( getValue() );
                checkProperty();
            }

            virtual void store()
            {
                save( uno::makeAny( (rtl::OUString) GetText() ) );
            }
        };

        struct AnyFontStyle : public AnyComboBox
        {
            AnyFontStyle( Widget *pWidget, rtl::OUString aPropName,
                          Widget::PropertyKind aPropKind, Window *pWinParent )
                : AnyComboBox( pWidget, aPropName, aPropKind, pWinParent )
            {
                InsertEntry( XubString::CreateFromAscii( "Bold" ) );
                InsertEntry( XubString::CreateFromAscii( "Italic" ) );
                InsertEntry( XubString::CreateFromAscii( "Bold Italic" ) );
                InsertEntry( XubString::CreateFromAscii( "Fett" ) );
                load();
            }
        };

        layout::FixedText *mpLabel;
        layout::CheckBox *mpFlag;
        AnyWidget *mpValue;

    public:
        PropertyEntry( layout::Window *pWinParent, AnyWidget *pAnyWidget )
        {
            mpLabel = new layout::FixedText( pWinParent );
            {
                // append ':' to aPropName
                rtl::OUStringBuffer buf( pAnyWidget->maPropName );
                buf.append( sal_Unicode (':') );
                mpLabel->SetText( buf.makeStringAndClear() );
            }
            mpValue = pAnyWidget;
            mpFlag = new layout::CheckBox( pWinParent );
            mpFlag->SetToggleHdl( LINK( mpValue, AnyWidget, FlagToggledHdl ) );
            mpValue->mpFlag = mpFlag;
        }

        ~PropertyEntry()
        {
#if DEBUG_PRINT
                fprintf(stderr, "REMOVING label, flag and value\n");
#endif
            delete mpLabel;
            delete mpFlag;
            delete mpValue;
        }

        // Use this factory rather than the constructor -- check for NULL
        static PropertyEntry *construct( Widget *pWidget, rtl::OUString aPropName,
                                         Widget::PropertyKind aPropKind, sal_uInt16 nType,
                                         layout::Window *pWinParent )
        {
            AnyWidget *pAnyWidget;
            switch (nType) {
                case uno::TypeClass_STRING:
                    if ( aPropName.compareToAscii( "FontStyleName" ) == 0 )
                    {
                        pAnyWidget = new AnyFontStyle( pWidget, aPropName, aPropKind, pWinParent );
                        break;
                    }
                    pAnyWidget = new AnyEdit( pWidget, aPropName, aPropKind, pWinParent );
                    break;
                case uno::TypeClass_SHORT:
                    if ( aPropName.compareToAscii( "Align" ) == 0 )
                    {
                        pAnyWidget = new AnyAlign( pWidget, aPropName, aPropKind, pWinParent );
                        break;
                    }
                    // otherwise, treat as any other number...
                case uno::TypeClass_LONG:
                case uno::TypeClass_UNSIGNED_LONG:
                    pAnyWidget = new AnyInteger( pWidget, aPropName, aPropKind, pWinParent );
                    break;
                case uno::TypeClass_FLOAT:
                case uno::TypeClass_DOUBLE:
                    pAnyWidget = new AnyFloat( pWidget, aPropName, aPropKind, pWinParent );
                    break;
                case uno::TypeClass_BOOLEAN:
                    pAnyWidget = new AnyCheckBox( pWidget, aPropName, aPropKind, pWinParent );
                    break;
                default:
                    return NULL;
            }
            return new PropertyEntry( pWinParent, pAnyWidget );
        }
    };

    layout::Window *mpParentWindow;

    std::list< PropertyEntry* > maPropertiesList;
    layout::FixedLine *mpSeparator;

    // some properties are obscure, or simply don't make sense in this
    // context. Let's just ignore them.
    // Maybe we could offer them in an expander or something...
    static bool toIgnore( rtl::OUString prop )
    {
        // binary search -- keep the list sorted alphabetically
        static char const *toIgnoreList[] = {
            "DefaultControl", "FocusOnClick", "FontCharWidth", "FontCharset",
            "FontEmphasisMark", "FontFamily", "FontHeight", "FontKerning", "FontName",
            "FontOrientation", "FontPitch", "FontRelief", "FontSlant", "FontStrikeout",
            "FontType", "FontWordLineMode", "HelpText", "HelpURL", "MultiLine",
            "Printable", "Repeat", "RepeatDelay", "Tabstop"
        };

#if 0
        // checks list sanity -- enable this when you add some entries...
        for ( unsigned int i = 1; i < sizeof( toIgnoreList )/sizeof( char * ); i++ )
        {
            if ( strcmp(toIgnoreList[i-1], toIgnoreList[i]) >= 0 )
            {
                printf("ignore list not ordered properly: "
                       "'%s' should come before '%s'\n",
                       toIgnoreList[i], toIgnoreList[i-1]);
                exit(-1);
            }
        }
#endif

        int min = 0, max = sizeof( toIgnoreList )/sizeof( char * ) - 1, mid, cmp;
        do {
            mid = min + (max - min)/2;
            cmp = prop.compareToAscii( toIgnoreList[ mid ] );
            if ( cmp > 0 )
                min = mid+1;
            else if ( cmp < 0 )
                max = mid-1;
            else
                return true;
        } while ( min <= max );
        return false;
    }

public:
    PropertiesList( layout::Dialog *dialog )
        : layout::Table( dialog, "properties-box" )
        , mpParentWindow( dialog ), mpSeparator( 0 )
    {
    }

    ~PropertiesList()
    {
        clear();
    }

private:
    // auxiliary, add properties from the peer to the list
    void addProperties( Widget *pWidget, Widget::PropertyKind rKind )
    {
        Widget::PropertyIterator it( pWidget, rKind );
        while ( it.hasNext() )
        {
            beans::Property prop = it.next();
            rtl::OUString name( prop.Name );
            if ( toIgnore( name ) )
                continue;
            sal_uInt16 type = static_cast< sal_uInt16 >( prop.Type.getTypeClass() );

            PropertyEntry *propEntry = PropertyEntry::construct(
                pWidget, name, rKind, type, mpParentWindow );

            if ( propEntry )
            {
                Add( propEntry->mpLabel, false, false );

                // HACK: one of these will return Null...
                Add( propEntry->mpValue->getWindow(), true, false );
                Add( propEntry->mpValue->getContainer(), true, false );

                Add( propEntry->mpFlag, false, false );
                maPropertiesList.push_back( propEntry );
            }
        }
    }

public:
    void selectedWidget( Widget *pWidget )
    {
        clear();

        if ( !pWidget )
            return;

        addProperties( pWidget, Widget::CONTAINER_PROPERTY );

        mpSeparator = new layout::FixedLine( mpParentWindow );
        // TODO: we may want to have to separate list widgets here...
        Add( mpSeparator, false, false, 3, 1 );

        addProperties( pWidget, Widget::WINDOW_PROPERTY );

        ShowAll( true );
    }

    void clear()
    {
        ///FIXME: crash
        Container::Clear();

        for ( std::list< PropertyEntry* >::iterator it = maPropertiesList.begin();
              it != maPropertiesList.end(); it++)
            delete *it;
        maPropertiesList.clear();

        delete mpSeparator;
        mpSeparator = NULL;
    }
};

IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, ApplyPropertyHdl, layout::Window *, pWin )
{
    (void) pWin;
    store();
    return 0;
}

IMPL_LINK( PropertiesList::PropertyEntry::AnyWidget, FlagToggledHdl, layout::CheckBox *, pCheck )
{
#if DEBUG_PRINT
    fprintf(stderr, "Property flag pressed -- is: %d\n", pCheck->IsChecked());
#endif
    if ( !mbBlockFlagCallback )
    {
        bool checked = pCheck->IsChecked();
        if ( !checked )  // revert
        {
#if DEBUG_PRINT
            fprintf(stderr, "revert\n");
#endif
            load();
        }
        else
        {
#if DEBUG_PRINT
            fprintf(stderr, "user can't dirty the flag!\n");
#endif
            // User can't flag the property as dirty
            // Actually, we may want to allow the designer to force a property to be stored.
            // Could be useful when the default value of some new property wasn't yet decided...
            CheckFlag( false, true );
        }
    }
#if DEBUG_PRINT
    else
        fprintf(stderr, "Property flag pressed -- BLOCKED\n");
#endif
    return 0;
}

IMPL_LINK( PropertiesList::PropertyEntry::AnyEdit, ExpandEditHdl, layout::PushButton *, pBtn )
{
    setAsMultiLine( pBtn->IsChecked() );
    return 0;
}

//** SortListBox auxiliary widget

class SortListBox
{        // For a manual sort ListBox; asks for a ListBox and Up/Down/Remove
         // buttons to wrap
    DECL_LINK( ItemSelectedHdl, layout::ListBox* );
    DECL_LINK( UpPressedHdl, layout::Button* );
    DECL_LINK( DownPressedHdl, layout::Button* );
    DECL_LINK( RemovePressedHdl, layout::Button* );
    layout::PushButton *mpUpButton, *mpDownButton, *mpRemoveButton;

protected:
    layout::ListBox *mpListBox;

    virtual void upPressed( USHORT nPos )
    {
        XubString str = mpListBox->GetSelectEntry();
        mpListBox->RemoveEntry( nPos );
        nPos = mpListBox->InsertEntry( str, nPos-1 );
        mpListBox->SelectEntryPos( nPos );
    }

    virtual void downPressed( USHORT nPos )
    {
        XubString str = mpListBox->GetSelectEntry();
        mpListBox->RemoveEntry( nPos );
        nPos = mpListBox->InsertEntry( str, nPos+1 );
        mpListBox->SelectEntryPos( nPos );
    }

    virtual void removePressed( USHORT nPos )
    {
        mpListBox->RemoveEntry( nPos );
    }

    virtual void itemSelected( USHORT nPos )
    {
        // if we had some XLayoutContainer::canAdd() or maxChildren() function
        // we could make a function to check if we can move selected and enable/
        // /disable the move buttons as appropriate

        if ( nPos == LISTBOX_ENTRY_NOTFOUND )
        {
            mpUpButton->Disable();
            mpDownButton->Disable();
            mpRemoveButton->Disable();
        }
        else
        {
            mpUpButton->Enable();
            mpDownButton->Enable();
            mpRemoveButton->Enable();
        }
    }

public:
    SortListBox( layout::ListBox *pListBox, layout::PushButton *pUpButton, layout::PushButton *pDownButton,
                 layout::PushButton *pRemoveButton )
        : mpUpButton( pUpButton), mpDownButton( pDownButton), mpRemoveButton( pRemoveButton ),
          mpListBox( pListBox )
    {
        mpListBox->SetSelectHdl( LINK( this, SortListBox, ItemSelectedHdl ) );

        mpUpButton->SetModeImage( layout::Image ( "res/commandimagelist/lc_moveup.png" ) );
        mpUpButton->SetImageAlign( IMAGEALIGN_LEFT );
        mpUpButton->SetClickHdl( LINK( this, SortListBox, UpPressedHdl ) );

        mpDownButton->SetModeImage( layout::Image ( "res/commandimagelist/lc_movedown.png" ) );
        mpDownButton->SetImageAlign( IMAGEALIGN_LEFT );
        mpDownButton->SetClickHdl( LINK( this, SortListBox, DownPressedHdl ) );

        // "res/commandimagelist/lch_delete.png", "res/commandimagelist/lc_delete.png"
        mpRemoveButton->SetModeImage( layout::Image ( "res/commandimagelist/sc_closedoc.png" ) );
        mpRemoveButton->SetImageAlign( IMAGEALIGN_LEFT );
        mpRemoveButton->SetClickHdl( LINK( this, SortListBox, RemovePressedHdl ) );

        // fire an un-select event
        itemSelected( LISTBOX_ENTRY_NOTFOUND );
    }

    virtual ~SortListBox();
};

SortListBox::~SortListBox()
{
    delete mpListBox;
    delete mpUpButton;
    delete mpDownButton;
    delete mpRemoveButton;
}

IMPL_LINK( SortListBox, UpPressedHdl, layout::Button *, pBtn )
{
    (void) pBtn;
    USHORT pos = mpListBox->GetSelectEntryPos();
    if ( pos > 0 && pos != LISTBOX_ENTRY_NOTFOUND )
        upPressed( pos );
    return 0;
}

IMPL_LINK( SortListBox, DownPressedHdl, layout::Button *, pBtn )
{
    (void) pBtn;
    USHORT pos = mpListBox->GetSelectEntryPos();
    if ( pos < mpListBox->GetEntryCount() && pos != LISTBOX_ENTRY_NOTFOUND )
        downPressed( pos );
    return 0;
}

IMPL_LINK( SortListBox, RemovePressedHdl, layout::Button *, pBtn )
{
    (void) pBtn;
    USHORT pos = mpListBox->GetSelectEntryPos();
    if ( pos != LISTBOX_ENTRY_NOTFOUND )
        removePressed( pos );
    return 0;
}

IMPL_LINK( SortListBox, ItemSelectedHdl, layout::ListBox *, pList )
{
    (void) pList;
    USHORT pos = mpListBox->GetSelectEntryPos();
    itemSelected( pos );
    return 0;
}

//** LayoutTree widget

class LayoutTree : public SortListBox
{
public:
    struct Listener
    {
        virtual void widgetSelected( Widget *pWidget ) = 0;
    };

private:
    Listener *mpListener;

public:
    Widget *mpRootWidget;

    LayoutTree( layout::Dialog *dialog )
        : SortListBox( new layout::ListBox( dialog, "layout-tree" ),
                       new layout::PushButton( dialog, "layout-up-button" ),
                       new layout::PushButton( dialog, "layout-down-button" ),
                       new layout::PushButton( dialog, "layout-remove-button" ) )
    {
        layout::PeerHandle handle = dialog->GetPeerHandle( "preview-box" );
        uno::Reference< awt::XLayoutConstrains > xWidget( handle, uno::UNO_QUERY );
        mpRootWidget = new Widget( xWidget, "root" );
    }

    virtual ~LayoutTree();

    Widget *getWidget( int nPos )
    {
        if ( nPos != LISTBOX_ENTRY_NOTFOUND )
            return FlatLayout::get( mpRootWidget, nPos );
        return NULL;
    }

    Widget *getSelectedWidget()
    {
        Widget *pWidget = getWidget( mpListBox->GetSelectEntryPos() );
        if ( !pWidget )  // return root, if none selected
            pWidget = mpRootWidget;
        return pWidget;
    }

    void selectWidget( Widget *pWidget )
    {
        int pos = FlatLayout::get( mpRootWidget, pWidget );
        if ( pos == -1 )
            // if asked to select hidden root, select visible root
            pos = 0;
        mpListBox->SelectEntryPos( sal::static_int_cast< USHORT >( pos ) );
    }

    void rebuild()
    {
        struct inner
        {
            // pads a string with whitespaces
            static rtl::OUString padString( rtl::OUString name, int depth )
            {
                rtl::OStringBuffer aBuf( depth * 4 + name.getLength() + 2 );
                for (int i = 0; i < depth; i++)
                    aBuf.append( "    " );
                aBuf.append( rtl::OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ) );
                return rtl::OUString( aBuf.getStr(), aBuf.getLength(),
                                      RTL_TEXTENCODING_UTF8 );
            }
        };

        mpListBox->Clear();
        for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) )
            mpListBox->InsertEntry( inner::padString( i->getLabel(), i->getDepth()-1 ) );

        // any selection, no longer is. ListBox doesn't fire the event on this case;
        // force it.
        itemSelected( LISTBOX_ENTRY_NOTFOUND );
    }

    void setListener( Listener *pListener )
    { mpListener = pListener; }

    // print in XML format...

    static rtl::OUString toXMLNaming (const rtl::OUString &string)
    {
        rtl::OUStringBuffer buffer (string.getLength());
        sal_Unicode *str = string.pData->buffer;
        for (int i = 0; i < string.getLength(); i++) {
            if ( str[i] >= 'A' && str[i] <= 'Z' )
            {
                if ( i > 0 )
                    buffer.append ((sal_Unicode) '-');
                buffer.append ((sal_Unicode) (str[i] - 'A' + 'a'));
            }
            else
                buffer.append ((sal_Unicode) str[i]);
        }

        return buffer.makeStringAndClear();
    }

    void print()
    {
        printf("\t\tExport:\n");
        printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
               "<dialog xmlns=\"http://openoffice.org/2007/layout\"\n"
               "        xmlns:cnt=\"http://openoffice.org/2007/layout/container\"\n"
               "        id=\"dialog\" title=\"Unnamed\" sizeable=\"true\" >\n");

        for ( Widget *i = FlatLayout::next( mpRootWidget ); i; i = FlatLayout::next( i ) )
        {
            for ( int d = i->getDepth(); d > 0; d-- )
                printf("    ");
            printf("<%s ", OUSTRING_CSTR( i->getUnoName() ) );

            for ( int kind = 0; kind < 2; kind++ )
            {
                Widget::PropertyKind wKind = kind == 0 ? Widget::WINDOW_PROPERTY
                    : Widget::CONTAINER_PROPERTY;
                Widget::PropertyIterator it( i, wKind );
                while ( it.hasNext() )
                {
                    beans::Property prop = it.next();
                    if ( !i->isPropertyTouched( prop.Name, wKind ) )
                        continue;

                    rtl::OUString value = i->getProperty( prop.Name, wKind );
                    if ( prop.Type.getTypeClass() == uno::TypeClass_BOOLEAN )
                    {
                        if ( value.compareToAscii( "0" ) )
                            value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("false") );
                        else
                            value = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("true") );
                    }

                    if ( value.getLength() > 0 )
                        printf("%s%s=\"%s\" ",
                               kind == 0 ? "" : "cnt:",
                               OUSTRING_CSTR( toXMLNaming( prop.Name ) ), OUSTRING_CSTR( value )
                            );

                }
            }
            printf("/>\n");
        }
        printf("</dialog>\n");
    }

protected:
    virtual void upPressed( USHORT nPos )
    {
        Widget *pWidget = getWidget( nPos );
        if ( FlatLayout::moveWidget( pWidget, true ) )
            rebuild();
        selectWidget( pWidget );
    }

    virtual void downPressed( USHORT nPos )
    {
        Widget *pWidget = getWidget( nPos );
        if ( FlatLayout::moveWidget( pWidget, false ) )
            rebuild();
        selectWidget( pWidget );
    }

    virtual void removePressed( USHORT nPos )
    {
        Widget *pWidget = getWidget( nPos );
        if ( pWidget )
        {
            pWidget->up()->removeChild( pWidget );
            delete pWidget;
            rebuild();
        }
    }

    virtual void itemSelected( USHORT nPos )
    {
        mpListener->widgetSelected( getWidget( nPos ) );
        SortListBox::itemSelected( nPos );
    }
};

LayoutTree::~LayoutTree()
{
    delete mpRootWidget;
}

//** EditorImpl

class EditorImpl : public LayoutTree::Listener
{
    void createWidget( const char *unoName );

    PropertiesList *mpPropertiesList;
    LayoutTree *mpLayoutTree;

    layout::PushButton *pImportButton, *pExportButton;
#ifdef FILEDLG
    FileDialog *pImportDialog;
#endif
    DECL_LINK( ImportButtonHdl, layout::PushButton* );
    DECL_LINK( ExportButtonHdl, layout::PushButton* );
#ifdef FILEDLG
    DECL_LINK( ImportDialogHdl, FileDialog* );
#endif

    // framework stuff
    uno::Reference< lang::XMultiServiceFactory > mxFactory;
    uno::Reference< awt::XToolkit > mxToolkit;
    uno::Reference< awt::XWindow > mxToplevel;

    virtual void widgetSelected( Widget *pWidget );
    DECL_LINK( CreateWidgetHdl, layout::Button* );

    std::list< layout::PushButton *> maCreateButtons;

public:

    EditorImpl( layout::Dialog *dialog,
                // we should probable open this channel (or whatever its called) ourselves
                uno::Reference< lang::XMultiServiceFactory > xMSF );
    virtual ~EditorImpl();

    void loadFile( const rtl::OUString &aTestFile );
};

EditorImpl::EditorImpl( layout::Dialog *dialog,
                        uno::Reference< lang::XMultiServiceFactory > xFactory )
    : mxFactory( xFactory )
    , mxToplevel( dialog->GetPeerHandle( "dialog" ), uno::UNO_QUERY )
    // FIXME: any of these should work
    //dialog->getContext()->getRoot(), uno::UNO_QUERY )
    // dialog->GetPeer(), uno::UNO_QUERY )
{
#if DEBUG_PRINT
    fprintf (stderr, "EditorImpl()\n");
#endif
    // framework
    mxToolkit = uno::Reference< awt::XToolkit >(
        mxFactory->createInstance(
            rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ),
        uno::UNO_QUERY );
    OSL_ASSERT( mxToolkit.is() );

    // custom widgets
#if DEBUG_PRINT
    fprintf (stderr, "custom widgets\n");
#endif
    mpPropertiesList = new PropertiesList( dialog );

    mpLayoutTree = new LayoutTree( dialog );
    mpLayoutTree->setListener( this );

/*    if ( xImport.is() )
      mpLayoutTree->getWidget( -1 )->addChild( new Widget( xImport, "import" ) );*/

    // create buttons
    layout::Container aWidgets( dialog, "create-widget" );
    layout::Container aContainers( dialog, "create-container" );
    for ( int i = 0; i < WIDGETS_SPECS_LEN; i++ )
    {
        layout::PushButton *pBtn = new layout::PushButton( (layout::Window *) dialog );
        pBtn->SetText( rtl::OUString::createFromAscii( WIDGETS_SPECS[ i ].pLabel ) );
        pBtn->SetClickHdl( LINK( this, EditorImpl, CreateWidgetHdl ) );
        if ( WIDGETS_SPECS[ i ].pIconName != NULL )
        {
            rtl::OString aPath ("res/commandimagelist/");
            aPath += WIDGETS_SPECS[ i ].pIconName;
            layout::Image aImg( aPath );
            pBtn->SetModeImage( aImg );
            pBtn->SetImageAlign( IMAGEALIGN_LEFT );
        }
        pBtn->Show();
        maCreateButtons.push_back( pBtn );
        layout::Container *pBox = WIDGETS_SPECS[ i ].bIsContainer ? &aContainers : &aWidgets;
        pBox->Add( pBtn );
    }

#ifdef FILEDLG
    fprintf(stderr,"creating file dialog\n");
    pImportDialog = new FileDialog( NULL/*(layout::Window *) dialog*/, 0 );
    fprintf(stderr,"connecting it\n");
    pImportDialog->SetFileSelectHdl( LINK( this, EditorImpl, ImportDialogHdl ) );
    fprintf(stderr,"done file dialog\n");
#endif

/*    pImportButton = new layout::PushButton( dialog, "import-button" );
    pImportButton->SetClickHdl( LINK( this, EditorImpl, ImportButtonHdl ) );*/
    pExportButton = new layout::PushButton( dialog, "export-button" );
    pExportButton->SetClickHdl( LINK( this, EditorImpl, ExportButtonHdl ) );
}

EditorImpl::~EditorImpl()
{
    delete mpPropertiesList;
    delete mpLayoutTree;
    for ( std::list< layout::PushButton * >::const_iterator i = maCreateButtons.begin();
          i != maCreateButtons.end(); i++)
        delete *i;
    delete pImportButton;
    delete pExportButton;
#ifdef FILEDLG
    delete pImportDialog;
#endif
}

void EditorImpl::loadFile( const rtl::OUString &aTestFile )
{
    fprintf( stderr, "TEST: layout instance\n" );
    uno::Reference< awt::XLayoutRoot > xRoot
        ( new EditorRoot( mxFactory, mpLayoutTree->mpRootWidget ) );

/*
  mxMSF->createInstance
  ( ::rtl::OUString::createFromAscii( "com.sun.star.awt.Layout" ) ),
  uno::UNO_QUERY );
*/
    if ( !xRoot.is() )
    {
        throw uno::RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("could not create awt Layout component!") ),
            uno::Reference< uno::XInterface >() );
    }

#if DEBUG_PRINT
    fprintf( stderr, "TEST: initing root\n" );
#endif

    uno::Reference< lang::XInitialization > xInit( xRoot, uno::UNO_QUERY );
    if ( !xInit.is() )
    {
        throw uno::RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("Layout has no XInitialization!") ),
            uno::Reference< uno::XInterface >() );
    }

#if DEBUG_PRINT
    fprintf( stderr, "TEST: running parser\n" );
#endif
    uno::Sequence< uno::Any > aParams( 1 );
    aParams[0] <<= aTestFile;
#if DEBUG_PRINT
    fprintf( stderr, "TEST: do it\n" );
#endif
    xInit->initialize( aParams );
#if DEBUG_PRINT
    fprintf( stderr, "TEST: file loaded\n" );
#endif

    mpLayoutTree->rebuild();
}

void EditorImpl::createWidget( const char *name )
{
    Widget *pWidget = mpLayoutTree->getSelectedWidget();

    Widget *pChild = new Widget( rtl::OUString(), mxToolkit, uno::Reference< awt::XLayoutContainer >( mxToplevel, uno::UNO_QUERY ), rtl::OUString::createFromAscii( name ), awt::WindowAttribute::SHOW );
    if ( !pWidget->addChild( pChild ) )
    {
        delete pChild;
        // we may want to popup an error message
    }
    else
    {
        mpLayoutTree->rebuild();
        mpLayoutTree->selectWidget( pWidget );
    }
}

void EditorImpl::widgetSelected( Widget *pWidget )
{
    // we know can't add widget to a non-container, so let's disable the create
    // buttons then. Would be nice to have a method to check if a container is
    // full as well...
    if ( !pWidget || pWidget->isContainer() )
    {
        for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
              it != maCreateButtons.end(); it++)
            (*it)->Enable();
    }
    else
    {
        for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
              it != maCreateButtons.end(); it++)
            (*it)->Disable();
    }

    mpPropertiesList->selectedWidget( pWidget );
}

IMPL_LINK( EditorImpl, CreateWidgetHdl, layout::Button *, pBtn )
{
    int i = 0;
    for ( std::list< layout::PushButton *>::const_iterator it = maCreateButtons.begin();
          it != maCreateButtons.end(); it++, i++ )
    {
        if ( pBtn == *it )
            break;
    }
    OSL_ASSERT( i < WIDGETS_SPECS_LEN );
    createWidget( WIDGETS_SPECS[i].pName );
    return 0;
}

IMPL_LINK( EditorImpl, ImportButtonHdl, layout::PushButton *, pBtn )
{
    (void) pBtn;
#if DEBUG_PRINT
    fprintf(stderr, "IMPORT!\n");
#endif
#ifdef FILEDLG
    pImportDialog->Execute();
#endif

    return 0;
}

#ifdef FILEDLG
IMPL_LINK( EditorImpl, ImportDialogHdl, FileDialog *, pDialog )
{
    UniString path = pDialog->GetPath();
//fprintf(stderr, "Executing import dialog!\n");

#if DEBUG_PRINT
    fprintf(stderr, "got import file: %s\n",rtl::OUStringToOString( path, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif

    return 0;
}
#endif

IMPL_LINK( EditorImpl, ExportButtonHdl, layout::PushButton *, pBtn )
{
    (void) pBtn;
    mpLayoutTree->print();
    return 0;
}

//** Editor, the Dialog

Editor::Editor( uno::Reference< lang::XMultiServiceFactory > xFactory,
                rtl::OUString aFile )
    : layout::Dialog( (Window*) (NULL), "editor.xml", "dialog" )
    , mpImpl( new EditorImpl( this, xFactory ) )
{
    if ( aFile.getLength() )
        mpImpl->loadFile( aFile );

    // parent:
    FreeResource();
}

Editor::~Editor()
{
    delete mpImpl;
}
