/*
  Copyright (c) 2000 Caldera Systems

  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.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <qlineedit.h>
#include <qlabel.h>

#include <kdebug.h>
#include <klistbox.h>
#include <klocale.h>
#include <kprocess.h>

#include "keyboardpageimpl.h"
#include "keyboardpageimpl.moc"
#include "kxdata.h"

// !$@## X includes
#undef FocusIn
#undef FocusOut

KeyboardPage::KeyboardPage( QWidget *parent, const char *name )
    : KeyboardPageBase( parent, name )
{
    connect( m_models, SIGNAL( currentChanged( QListBoxItem * ) ),
             this, SIGNAL( changed() ) );
    connect( m_layouts, SIGNAL( currentChanged( QListBoxItem * ) ),
             this, SIGNAL( changed() ) );

    m_test->installEventFilter(this);

    originalKeyboard = m_data->currentKeyboards()[ 0 ];
}

KeyboardPage::~KeyboardPage()
{
}

bool
KeyboardPage::get_layout_from_item(QListBoxItem *item,KXKeyboardLayout &layout)
{
    KXKeyboardLayoutList layouts = m_data->keyboardLayouts();
    QValueList<KXKeyboardLayout>::ConstIterator lIt = layouts.begin();
    QValueList<KXKeyboardLayout>::ConstIterator lEnd = layouts.end();
    for (; lIt != lEnd; ++lIt ) {
	layout = *lIt;
	if ( layout.name() == item->text() )
	    return true;;
    }
    fprintf(stderr,"failed get_layout_from_item\n");
    return false;
}

bool
KeyboardPage::get_model_from_item(QListBoxItem *item,KXKeyboardModel &model)
{
    KXKeyboardModelList models = m_data->keyboardModels();
    QValueList<KXKeyboardModel>::ConstIterator mIt = models.begin();
    QValueList<KXKeyboardModel>::ConstIterator mEnd = models.end();
    for (; mIt != mEnd; ++mIt ) {
	model = *mIt;
	if ( model.name() == item->text() )
	    return true;
    }
    fprintf(stderr,"failed get_model_from_item\n");
    return false;
}

bool KeyboardPage::eventFilter( QObject *obj, QEvent *e )
{
    if ( obj == m_test )
    {
        if ( e->type() == QEvent::FocusIn )
        {
            kdDebug() << "focusin" << endl;

	    KXKeyboardLayout layout;
	    KXKeyboardModel  model;

	    if (get_model_from_item(m_models->item(m_models->currentItem()),model) &&
	    	get_layout_from_item(m_layouts->item(m_layouts->currentItem()),layout)
	    )
		set(layout.id(),model.id()); 
        }
        else if ( e->type() == QEvent::FocusOut )
        {
            kdDebug() << "focusout" << endl;

            set( KXData::global()->currentKeyboards().first().layout().id(),
                 KXData::global()->currentKeyboards().first().model().id() );
        }
    }
    return false;
}

void KeyboardPage::load()
{
    m_layouts->clear();
    m_models->clear();

    KXKeyboardData currentKeyboard = m_data->currentKeyboards()[ 0 ];

    KXKeyboardLayoutList layouts = m_data->keyboardLayouts();
    QValueList<KXKeyboardLayout>::ConstIterator lIt = layouts.begin();
    QValueList<KXKeyboardLayout>::ConstIterator lEnd = layouts.end();
    for (; lIt != lEnd; ++lIt )
    {
        KXKeyboardLayout layout = *lIt;

        m_layouts->insertItem( layout.name() );
        if ( currentKeyboard.layout().name() == layout.name() )
        {
            QListBoxItem *item = m_layouts->findItem( layout.name() );
            m_layouts->setSelected( item, true );
        }
    }

    emit enableForward( false );

    KXKeyboardModelList models = m_data->keyboardModels();
    QValueList<KXKeyboardModel>::ConstIterator mIt = models.begin();
    QValueList<KXKeyboardModel>::ConstIterator mEnd = models.end();
    for (; mIt != mEnd; ++mIt )
    {
        KXKeyboardModel model = *mIt;

        m_models->insertItem( model.name() );
        if ( currentKeyboard.model().name() == model.name() )
        {
            QListBoxItem *item = m_models->findItem( model.name() );
            m_models->setSelected( item, true );

            emit enableForward( true );
        }
    }

    m_layouts->sort();
    m_models->sort();

    m_layouts->centerCurrentItem();
    m_models->centerCurrentItem();
}

void KeyboardPage::save()
{
    kdDebug() << "KeyboardPage::save()" << endl;

    QListBoxItem *item = m_models->firstItem();
    while ( item )
    {
        if ( item->isSelected() )
        {
	    KXKeyboardModel model;

	    if (get_model_from_item(item,model))
		m_data->currentKeyboards()[ 0 ].setModel( model );
            break;
        }
        item = item->next();
    }

    item = m_layouts->firstItem();
    while ( item )
    {
        if ( item->isSelected() )
        {
	    KXKeyboardLayout layout;
	    if (get_layout_from_item(item,layout))
		m_data->currentKeyboards()[ 0 ].setLayout( layout );
            break;
        }
        item = item->next();
    }
}

void KeyboardPage::revert()
{
    set( originalKeyboard.layout().id(), originalKeyboard.model().id() );
}

void KeyboardPage::set( const QString &layout, const QString &model )
{
    kdDebug() << "void KeyboardPage::set() " << layout << " " << model << endl;

    QApplication::flushX();

    KProcess proc;
    proc << "setxkbmap" << "-rules" << "xfree86" << "-model" << model.local8Bit()
         << "-layout" << layout.local8Bit();
    proc.start(KProcess::Block);
}

QString KeyboardPage::quickHelp() const
{
    return(i18n("<h1>Select Keyboard Type</h1>"
                "<p>In this screen you select your keyboard <em>model</em> (in the top window) "
                "and the keyboard <em>layout</em> (in the bottom window). The model of the "
                "keyboard describes the keyboard hardware. The layout determines things "
                "like what character will appear on the screen when you press a key.</p>"));
}
