/***************************************************************************
                          tagxml.cpp  -  description
                             -------------------
    begin                : � � 25 14:34:07 EEST 2000
    copyright            : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <pdima@users.sourceforge.net,yshurik@penguinpowered.com,sequitur@easystreet.com>
                           (C) 2002-2004 by Andras Mantia <amantia@kde.org>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "tagxml.h"
#include "tagattr.h"
#include <klineedit.h>
#include <kdebug.h>
#include <tdelocale.h>

#include <tqcheckbox.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>

#include "styleeditor.h"

Tagxml::Tagxml( TQDomNode &d, TQTag *dtdTag, TQWidget *parent, const char *name)
    :TQWidget(parent,name), TagWidget(parent,name), doc(d)
{
    initialize(d, dtdTag);
}

Tagxml::Tagxml( TQDomNode &d, TQTag *dtdTag, const TQString& selection, TQWidget *parent, const char *name)
    : TQWidget(parent,name), TagWidget(parent,name), doc(d), m_selection(selection)
{
    initialize(d, dtdTag);
}

Tagxml::~Tagxml()
{
}

void Tagxml::initialize(TQDomNode &d, TQTag *dtdTag)
{
    m_dtd = dtdTag->parentDTD;
    m_dtdTag = dtdTag;
    TQGridLayout *grid = new TQGridLayout( this );
    grid->setSpacing( 13 );
    grid->setMargin( 11 );
    m_firstItem = 0L;
//parse the tag XML file, in order to build up the dialog
    for ( TQDomNode n = d.firstChild(); !n.isNull(); n = n.nextSibling() )
    {
        TQDomNode location = findChild(n,"location");
        if ( location.isNull() )
            continue;

     //debug( n.nodeName() );

        TQDomElement el = location.toElement();

        int row = el.attribute("row","0").toInt();
        int col = el.attribute("col","0").toInt();
        int colspan = el.attribute("colspan","1").toInt()-1;
        int rowspan = el.attribute("rowspan","1").toInt()-1;

        location = findChild(n,"textlocation");
        el = location.toElement();
        int textrow = el.attribute("row","0").toInt();
        int textcol = el.attribute("col","0").toInt();
        int textcolspan = el.attribute("colspan","1").toInt()-1;
        int textrowspan = el.attribute("rowspan","1").toInt()-1;

     // tqDebug("%s col:%d row:%d cs:%d, rs:%d", n.nodeName().data(), col,row,colspan,rowspan );

        TQString tip;
        TQDomNode tooltip = findChild( n ,"tooltip" );
        if ( !tooltip.isNull() ) {
            if ( tooltip.firstChild().isText() ) {
                TQDomText text = tooltip.firstChild().toText();
                tip = text.data();
            }
        }
        TQString whatsThis;
        TQDomNode what = findChild( n ,"whatsthis" );
        if ( !what.isNull() ) {
            if ( what.firstChild().isText() ) {
                TQDomText text = what.firstChild().toText();
                whatsThis = text.data();
            }
        }

        if ( n.nodeName() == "label" ) //a static label
        {
            TQLabel *label = new TQLabel(this);
            TQDomElement ltext = findChild(n,"text").toElement();
            if ( !ltext.isNull() )
                label->setText( ltext.text().isEmpty() ? TQString("") : (ltext.text()+":") );

            if ( !tip.isNull() )
                TQToolTip::add( label, tip );
            if ( !whatsThis.isNull() )
                TQWhatsThis::add( label, whatsThis );

            grid->addMultiCellWidget( label, row, row+rowspan, col,  col+colspan );
        }

        if ( n.nodeName() == "attr" ) //an attribute
        {

            TQDomElement el(n.toElement());
            TQString type = el.attribute("type","input");

            TQDomElement ltext = findChild(n,"text").toElement();
            if ( !ltext.isNull() && (type != "check") ) //if there is a text label for the attribute
            {
                TQLabel *label = new TQLabel(this);
                label->setText( ltext.text().isEmpty() ? TQString("") : (ltext.text()+":") );

                if ( !tip.isNull() )
                    TQToolTip::add( label, tip );
                if ( !whatsThis.isNull() )
                    TQWhatsThis::add( label, whatsThis );
                grid->addMultiCellWidget( label, textrow, textrow+textrowspan, textcol,  textcol+textcolspan );
            }


        //look for the different attribute types
            if ( type == "input" )
            {
                KLineEdit *w = new KLineEdit(this);
                grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );
           
                if ( !tip.isNull() )
                    TQToolTip::add( w, tip );
                if ( !whatsThis.isNull() )
                    TQWhatsThis::add( w, whatsThis );

                Attr_line *attr = new Attr_line(el, w, m_dtdTag);
                attributes.append(attr);
                if (!m_firstItem)
                    m_firstItem = w;
            } 
            else
                if ( type == "check" )
            {
                TQCheckBox *w = new TQCheckBox(this);
                grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );

                TQDomElement ltext = findChild(n,"text").toElement();
                if ( !ltext.isNull() )
                    w->setText( ltext.text() );
                if ( !tip.isNull() )
                    TQToolTip::add( w, tip );
                if ( !whatsThis.isNull() )
                    TQWhatsThis::add( w, whatsThis );

                Attr_check *attr = new Attr_check(el, w, m_dtdTag);
                attributes.append(attr);
                if (!m_firstItem)
                    m_firstItem = w;
            } else
                if ( type == "list" )
                {
                    TQComboBox *w = new TQComboBox(true, this);
                    grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );
                    if ( !tip.isNull() )
                        TQToolTip::add( w, tip );
                    if ( !whatsThis.isNull() )
                        TQWhatsThis::add( w, whatsThis );
                    Attr_list *attr = new Attr_list(el, w, dtdTag);
                    attributes.append(attr);
                    if (!m_firstItem)
                        m_firstItem = w;
                } else
                    if ( type == "color" )
                    {
                        ColorCombo *w = new ColorCombo(this);
                        grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );

                        if ( !tip.isNull() )
                            TQToolTip::add( w, tip );
                        if ( !whatsThis.isNull() )
                            TQWhatsThis::add( w, whatsThis );

                        Attr_color *attr = new Attr_color(el, w, m_dtdTag);
                        attributes.append(attr);
                        if (!m_firstItem)
                            m_firstItem = w;
                    } else
                        if ( type == "url" )
                        {
                            FileCombo *w = new FileCombo(baseURL, this);
                            grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );
           
                            if ( !tip.isNull() )
                                TQToolTip::add( w, tip );
                            if ( !whatsThis.isNull() )
                                TQWhatsThis::add( w, whatsThis );
                            Attr_file *attr = new Attr_file(el, w, m_dtdTag);
                            attributes.append(attr);
                            if (!m_firstItem)
                                m_firstItem = w;
                        }
        
                        else
                            if ( type == "css-style" )
                        {
                            StyleEditor *w = new StyleEditor(this);
                            grid->addMultiCellWidget( w, row, row+rowspan, col,  col+colspan );

                            if ( !tip.isNull() )
                                TQToolTip::add( w, tip );
                            if ( !whatsThis.isNull() )
                                TQWhatsThis::add( w, whatsThis );

                            Attr_line *attr = new Attr_line(el, w->lineEdit(), m_dtdTag);
                            attributes.append(attr);
           
                            if (!m_firstItem)
                                m_firstItem = w;
           
                        }
        
        }

        if ( n.nodeName() == "spacer")
        {
            TQDomElement el = n.toElement();

            TQSpacerItem* spacer;

            if ( el.attribute("orientation","v") == "v" )
                spacer = new TQSpacerItem( 5, 10, TQSizePolicy::Fixed, TQSizePolicy::Expanding );
            else
                spacer = new TQSpacerItem( 10, 5, TQSizePolicy::Expanding, TQSizePolicy::Fixed );
            grid->addItem(spacer,row,col);
        }

    }
}

void Tagxml::focusToFirstItem()
{
  if(m_firstItem)
    m_firstItem->setFocus();
}

void Tagxml::readAttributes( TQDict<TQString> *d )
{
  TQString name,value;

  Attr * attr = attributes.first();
   while ( attr ) {
     name = attr->attrName();
     value = attr->value();

     if ( value.isEmpty() )
        d->remove(name);
     else
     {
      if ( dynamic_cast<Attr_check *>(attr) ) // checkbox
      {      
        if (value == "checked")
        {
          if (m_dtd->booleanAttributes == "simple")
          {
            d->replace(name, new TQString("") );
          } else
          {
            d->replace(name, new TQString(m_dtd->booleanTrue)); //it seems that browsers don't like <input disabled="false">, so if a checkbox is false, don't put in the tag at all
          }
        }  
        else  
        {
          d->remove(name);
        }
/*        } else
        {
          value = (value == "checked")?m_dtd->booleanTrue:m_dtd->booleanFalse;
          d->replace(name, new TQString(value));
        } */
      } else
      if (dynamic_cast<Attr_file *>(attr))
      {
//        value = KURL::encode_string(value);
        d->replace(name, new TQString(value));
      } else {
        value.replace(TQRegExp("&(?!amp;)"), "&amp;");
        d->replace(name, new TQString(value) );
      }
    }


    attr = attributes.next();
  }

}

void Tagxml::writeAttributes( TQDict<TQString> *d )
{
    TQString name,value;

    Attr * attr = attributes.first();
  
    int count = 0;
    while ( attr ) {

        name = attr->attrName();

        TQString *v = d->find(name);
        if ( v ) {
            v->replace("&amp;","&");
            if ( dynamic_cast<Attr_check *>(attr) ) // checkbox
                value = "checked";
            else
                if ( dynamic_cast<Attr_file *>(attr))
                    value = KURL::decode_string(*v);
            else
                value = *v;
        }
        else
        {
            value = "";
        
            Attribute* attrib = m_dtdTag->attribute(name);
            if(attrib && attrib->source.lower() == "selection")
                value = m_selection;
        }

        attr->setValue( value );

        attr = attributes.next();
        ++count;
    }
}

#include "tagxml.moc"
