/**************************************************************
 * 
 * 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 successful
    }
    // 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;
}
