/*
 Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
 
 Win32 port:
 Copyright (C) 2004 Jarosław Staniek <staniek@kde.org>
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.
 
 This library 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
 Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
 */

#include "kkeyserver.h"

#include <config.h>
#include <klocale.h>
#include <kglobal.h>
#include <kconfig.h>
#include <kconfiggroup.h>

namespace KKeyServer {
//---------------------------------------------------------------------
// Array Structures
//---------------------------------------------------------------------
    
struct ModInfo
{
	int modQt;
	const char* psName;
	QString* sLabel; // this struct is used in static objects, so must use a pointer here.
};

//---------------------------------------------------------------------
// Arrays
//---------------------------------------------------------------------

// Key names with this context are extracted elsewhere,
// no need for I18N_NOOP2's here.
#define KEYCTXT "keyboard-key-name"
static ModInfo g_rgModInfo[4] =
{
	{ Qt::SHIFT,   "Shift", 0 },
	{ Qt::CTRL,    "Ctrl", 0 },
	{ Qt::ALT,     "Alt", 0 },
	{ Qt::META,    "Meta", 0 }
};

//---------------------------------------------------------------------
// Initialization
//---------------------------------------------------------------------
static bool g_bInitializedKKeyLabels;
static bool g_bMacLabels;

static void intializeKKeyLabels()
{
	KConfigGroup cg( KGlobal::config(), "Keyboard" );
	g_rgModInfo[0].sLabel = new QString( cg.readEntry( "Label Shift", i18nc(KEYCTXT, g_rgModInfo[0].psName) ) );
	g_rgModInfo[1].sLabel = new QString( cg.readEntry( "Label Ctrl", i18nc(KEYCTXT, g_rgModInfo[1].psName) ) );
	g_rgModInfo[2].sLabel = new QString( cg.readEntry( "Label Alt", i18nc(KEYCTXT, g_rgModInfo[2].psName) ) );
	g_rgModInfo[3].sLabel = new QString( cg.readEntry( "Label Win", i18nc(KEYCTXT, g_rgModInfo[3].psName) ) );
	g_bMacLabels = (*g_rgModInfo[2].sLabel == "Command");
	g_bInitializedKKeyLabels = true;
    
}

//---------------------------------------------------------------------
// Public functions
//---------------------------------------------------------------------

static QString modToString( uint mod, bool bUserSpace )
{
	if( bUserSpace && !g_bInitializedKKeyLabels )
		intializeKKeyLabels();
    
	QString s;
	for( int i = 3; i >= 0; i-- ) {
		if( mod & g_rgModInfo[i].modQt ) {
			if( !s.isEmpty() )
				s += '+';
			s += (bUserSpace)
                ? *g_rgModInfo[i].sLabel
                : QString(g_rgModInfo[i].psName);
		}
	}
	return s;
}

QString modToStringUser( uint mod )
{
	return modToString( mod, true );
}

uint stringUserToMod( const QString& mod )
{
	QString s;
	for( int i = 3; i >= 0; i-- ) {
		if( mod.toLower() == g_rgModInfo[i].sLabel->toLower())
			return g_rgModInfo[i].modQt;
	}
	return 0;
}

bool isShiftAsModifierAllowed( int keyQt )
{
    // remove any modifiers
    keyQt &= ~Qt::KeyboardModifierMask;

    // Shift only works as a modifier with certain keys. It's not possible
    // to enter the SHIFT+5 key sequence for me because this is handled as
    // '%' by qt on my keyboard.
    // The working keys are all hardcoded here :-(
    if (keyQt >= Qt::Key_F1 && keyQt <= Qt::Key_F35)
        return true;

    if (QChar(keyQt).isLetter())
        return true;

    switch (keyQt) {
        case Qt::Key_Return:
        case Qt::Key_Space:
        case Qt::Key_Backspace:
        case Qt::Key_Backtab:
        case Qt::Key_Escape:
        case Qt::Key_Print:
        case Qt::Key_ScrollLock:
        case Qt::Key_Pause:
        case Qt::Key_PageUp:
        case Qt::Key_PageDown:
        case Qt::Key_Insert:
        case Qt::Key_Delete:
        case Qt::Key_Home:
        case Qt::Key_End:
        case Qt::Key_Up:
        case Qt::Key_Down:
        case Qt::Key_Left:
        case Qt::Key_Right:
        case Qt::Key_Enter:
        case Qt::Key_SysReq:
        case Qt::Key_CapsLock:
        case Qt::Key_NumLock:
        case Qt::Key_Help:
        case Qt::Key_Back:
        case Qt::Key_Forward:
        case Qt::Key_Stop:
        case Qt::Key_Refresh:
        case Qt::Key_Favorites:
        case Qt::Key_LaunchMedia:
        case Qt::Key_OpenUrl:
        case Qt::Key_HomePage:
        case Qt::Key_Search:
        case Qt::Key_VolumeDown:
        case Qt::Key_VolumeMute:
        case Qt::Key_VolumeUp:
        case Qt::Key_BassBoost:
        case Qt::Key_BassUp:
        case Qt::Key_BassDown:
        case Qt::Key_TrebleUp:
        case Qt::Key_TrebleDown:
        case Qt::Key_MediaPlay:
        case Qt::Key_MediaStop:
        case Qt::Key_MediaPrevious:
        case Qt::Key_MediaNext:
        case Qt::Key_MediaRecord:
        case Qt::Key_MediaPause:
        case Qt::Key_MediaTogglePlayPause:
        case Qt::Key_LaunchMail:
        case Qt::Key_Calculator:
        case Qt::Key_Memo:
        case Qt::Key_ToDoList:
        case Qt::Key_Calendar:
        case Qt::Key_PowerDown:
        case Qt::Key_ContrastAdjust:
        case Qt::Key_Standby:
        case Qt::Key_MonBrightnessUp:
        case Qt::Key_MonBrightnessDown:
        case Qt::Key_KeyboardLightOnOff:
        case Qt::Key_KeyboardBrightnessUp:
        case Qt::Key_KeyboardBrightnessDown:
        case Qt::Key_PowerOff:
        case Qt::Key_WakeUp:
        case Qt::Key_Eject:
        case Qt::Key_ScreenSaver:
        case Qt::Key_WWW:
        case Qt::Key_Sleep:
        case Qt::Key_LightBulb:
        case Qt::Key_Shop:
        case Qt::Key_History:
        case Qt::Key_AddFavorite:
        case Qt::Key_HotLinks:
        case Qt::Key_BrightnessAdjust:
        case Qt::Key_Finance:
        case Qt::Key_Community:
        case Qt::Key_AudioRewind:
        case Qt::Key_BackForward:
        case Qt::Key_ApplicationLeft:
        case Qt::Key_ApplicationRight:
        case Qt::Key_Book:
        case Qt::Key_CD:
        case Qt::Key_Clear:
        case Qt::Key_ClearGrab:
        case Qt::Key_Close:
        case Qt::Key_Copy:
        case Qt::Key_Cut:
        case Qt::Key_Display:
        case Qt::Key_DOS:
        case Qt::Key_Documents:
        case Qt::Key_Excel:
        case Qt::Key_Explorer:
        case Qt::Key_Game:
        case Qt::Key_Go:
        case Qt::Key_iTouch:
        case Qt::Key_LogOff:
        case Qt::Key_Market:
        case Qt::Key_Meeting:
        case Qt::Key_MenuKB:
        case Qt::Key_MenuPB:
        case Qt::Key_MySites:
        case Qt::Key_News:
        case Qt::Key_OfficeHome:
        case Qt::Key_Option:
        case Qt::Key_Paste:
        case Qt::Key_Phone:
        case Qt::Key_Reply:
        case Qt::Key_Reload:
        case Qt::Key_RotateWindows:
        case Qt::Key_RotationPB:
        case Qt::Key_RotationKB:
        case Qt::Key_Save:
        case Qt::Key_Send:
        case Qt::Key_Spell:
        case Qt::Key_SplitScreen:
        case Qt::Key_Support:
        case Qt::Key_TaskPane:
        case Qt::Key_Terminal:
        case Qt::Key_Tools:
        case Qt::Key_Travel:
        case Qt::Key_Video:
        case Qt::Key_Word:
        case Qt::Key_Xfer:
        case Qt::Key_ZoomIn:
        case Qt::Key_ZoomOut:
        case Qt::Key_Away:
        case Qt::Key_Messenger:
        case Qt::Key_WebCam:
        case Qt::Key_MailForward:
        case Qt::Key_Pictures:
        case Qt::Key_Music:
        case Qt::Key_Battery:
        case Qt::Key_Bluetooth:
        case Qt::Key_WLAN:
        case Qt::Key_UWB:
        case Qt::Key_AudioForward:
        case Qt::Key_AudioRepeat:
        case Qt::Key_AudioRandomPlay:
        case Qt::Key_Subtitle:
        case Qt::Key_AudioCycleTrack:
        case Qt::Key_Time:
        case Qt::Key_Select:
        case Qt::Key_View:
        case Qt::Key_TopMenu:
        case Qt::Key_Suspend:
        case Qt::Key_Hibernate:
        case Qt::Key_Launch0:
        case Qt::Key_Launch1:
        case Qt::Key_Launch2:
        case Qt::Key_Launch3:
        case Qt::Key_Launch4:
        case Qt::Key_Launch5:
        case Qt::Key_Launch6:
        case Qt::Key_Launch7:
        case Qt::Key_Launch8:
        case Qt::Key_Launch9:
        case Qt::Key_LaunchA:
        case Qt::Key_LaunchB:
        case Qt::Key_LaunchC:
        case Qt::Key_LaunchD:
        case Qt::Key_LaunchE:
        case Qt::Key_LaunchF:
            return true;

        default:
            return false;
    }
}

}
