/*
 * PreferencesApp.cpp
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * 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 (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

#include "swt.h"
#include "PreferencesApp.h"
#include "DuneApp.h"

#define DEFAULT_NEAR_CLIPPING_PLANE_DIST 0.05f 
#define DEFAULT_FAR_CLIPPING_PLANE_DIST 7000.0f
#define DEFAULT_MAX_INLINES_TO_LOAD 1024
#define DEFAULT_MAX_KEYS_IN_CHANNELVIEW 64

#define COMPANY_NAME "WhiteDune"
#define APP_NAME "dune"

PreferencesApp::PreferencesApp()
{
    _prefs = swLoadPreferences(COMPANY_NAME, APP_NAME);
    _showAllFields = GetBoolPreference("ShowAllFields", false);
    _rotationOrder = GetIntPreference("RotationOrder", EulOrdXYZs);
    _rotationTitle = "XYZs";
    _mouseMode = (MouseMode) GetIntPreference("MouseMode", MOUSE_EXAMINE);
    _handleMode = (HandleMode) GetIntPreference("HandleMode", HM_SELECTED);
    _handleMeshAlways = GetBoolPreference("HandleMeshAlways", false);
#ifdef HAVE_OLPC
    const char* handleSizeBuf = GetPreference("HandleSize", "5.0");
#else
    const char* handleSizeBuf = GetPreference("HandleSize", "3.0");
#endif
    _handleSize = atof(handleSizeBuf);
    const char* handleScaleBuf = GetPreference("HandleScale", "1.0");
    _handleScale = atof(handleScaleBuf);
    const char* pointSetSizeBuf = GetPreference("PointSetSize", "0.0");
    _pointSetSize = atof(pointSetSizeBuf);
    const char* epsilonBuf = GetPreference("HandleEpsilon", "0.008");
    _handleEpsilon = atof(epsilonBuf);
    char buf[128];
    const char *buf2;
    mysnprintf(buf, 127, "%f", DEFAULT_NEAR_CLIPPING_PLANE_DIST);
    buf2 = GetPreference("NearClippingPlaneDistance", buf); 
    if (atof(buf2) > 0)
        _nearClippingPlaneDist = atof(buf2);
    else {
        _nearClippingPlaneDist = DEFAULT_NEAR_CLIPPING_PLANE_DIST;
        swDebugf("NearClippingPlaneDistance preference");
        swDebugf(" must be greater zero\n");
        swDebugf("NearClippingPlaneDistance preference set to %f\n",
                 _nearClippingPlaneDist);
    }
    mysnprintf(buf, 127, "%f", DEFAULT_FAR_CLIPPING_PLANE_DIST);
    buf2 = GetPreference("FarClippingPlaneDistance", buf); 
    if (atof(buf2) > _nearClippingPlaneDist)
        _farClippingPlaneDist = atof(buf2);
    else {
        _nearClippingPlaneDist = DEFAULT_NEAR_CLIPPING_PLANE_DIST;
        _farClippingPlaneDist = DEFAULT_FAR_CLIPPING_PLANE_DIST;
        swDebugf("FarClippingPlaneDistance preference");
        swDebugf(" must be greater than NearClippingPlaneDistance preference\n");
        swDebugf("FarClippingPlaneDistance preference set to %f\n",
                 _farClippingPlaneDist);
        swDebugf("NearClippingPlaneDistance preference set to %f\n",
                 _nearClippingPlaneDist);
    }
    _xSymetricMode = GetBoolPreference("XSymetric", true);    
    _maxInlinesToLoad = GetIntPreference("MaxInlinesToLoad", 
                                         DEFAULT_MAX_INLINES_TO_LOAD);
    _maxKeysInChannelView = GetIntPreference("MaxKeysInChannelView", 
                                             DEFAULT_MAX_KEYS_IN_CHANNELVIEW);
    _X11ErrorsLimit = GetIntPreference("X11ErrorsLimit", 10);    
}

void
PreferencesApp::PreferencesDefaults()
{
    _showAllFields = false;
    _rotationOrder = EulOrdXYZs;
    _rotationTitle = "XYZs";
    _mouseMode = (MouseMode) MOUSE_EXAMINE;
    _handleMode = (HandleMode) HM_SELECTED;
    _handleMeshAlways = false;
    _handleSize = 3.0;
    _handleScale = 1.0;
    _pointSetSize = 0.0;
    _handleEpsilon = 0.01;
    _nearClippingPlaneDist = DEFAULT_NEAR_CLIPPING_PLANE_DIST;
    _farClippingPlaneDist = DEFAULT_FAR_CLIPPING_PLANE_DIST;
    _xSymetricMode = true;    
    _maxInlinesToLoad = DEFAULT_MAX_INLINES_TO_LOAD;
    _maxKeysInChannelView = DEFAULT_MAX_KEYS_IN_CHANNELVIEW;
}


void PreferencesApp::SavePreferences()
{
    char buf[128];
    SetBoolPreference("ShowAllFields", _showAllFields);
    SetIntPreference("RotationOrder", _rotationOrder);
    SetIntPreference("MouseMode", _mouseMode);
    SetIntPreference("HandleMode", _handleMode);
    SetBoolPreference("HandleMeshAlways", _handleMeshAlways);
    mysnprintf(buf, 127, "%f", _handleSize);
    SetPreference("HandleSize", buf);
    mysnprintf(buf, 127, "%f", _handleScale);
    SetPreference("HandleScale", buf);
    mysnprintf(buf, 127, "%f", _pointSetSize);
    SetPreference("PointSetSize", buf);
    mysnprintf(buf, 127, "%f", _handleEpsilon);
    SetPreference("HandleEpsilon", buf);
    mysnprintf(buf, 127, "%f", _nearClippingPlaneDist);
    SetPreference("NearClippingPlaneDistance", buf);
    mysnprintf(buf, 127, "%f", _farClippingPlaneDist);
    SetPreference("FarClippingPlaneDistance", buf);
    SetBoolPreference("XSymetric", _xSymetricMode);
    SetIntPreference("MaxInlinesToLoad", _maxInlinesToLoad); 
    SetIntPreference("MaxKeysInChannelView", _maxKeysInChannelView);
    SetIntPreference("X11ErrorsLimit", _X11ErrorsLimit);

    TheApp->EcmaScriptSavePreferences();
    TheApp->StereoViewSavePreferences();
    TheApp->InputSavePreferences();
    TheApp->OutputSavePreferences();
    TheApp->RouteViewSavePreferences();
    TheApp->StartWithSavePreferences();
    swSavePreferences(_prefs);
}

void PreferencesApp::SetShowAllFields(bool showAllFields)
{
    if (_showAllFields != showAllFields) {
        _showAllFields = showAllFields;
        TheApp->UpdateAllWindows();
    }
}

void PreferencesApp::SetRotationOrder(int rotationOrder)
{
    if (_rotationOrder != rotationOrder) {
        _rotationOrder = rotationOrder;
        TheApp->UpdateAllWindows();
    }
}

float PreferencesApp::GetHandleSize(void)
{
    if (TheApp->useStereo())
        return TheApp->GetStereoHandleSizeMult() * _handleSize;
    else
        return _handleSize;         
}

void PreferencesApp::SetPreferenceHandleSize(float size)
{
    _handleSize = size;         
    TheApp->UpdateAllWindows();
}

void PreferencesApp::SetPreferenceHandleScale(float scale)
{
    _handleScale = scale;         
    TheApp->UpdateAllWindows();
}

void PreferencesApp::SetPointSetSize(float size)
{
    _pointSetSize = size;         
    TheApp->UpdateAllWindows();
}

void PreferencesApp::SetHandleMode(HandleMode handleMode)
{
    if (_handleMode != handleMode) {
        _handleMode = handleMode;
        TheApp->UpdateAllWindows();
    }
}

void PreferencesApp::SetMouseMode(MouseMode mouseMode)
{
    if (_mouseMode != mouseMode)
        _mouseMode = mouseMode;
}

bool
PreferencesApp::GetBoolPreference(const char *key, bool defaultValue)
{
    return swGetIntPreference(_prefs, key, defaultValue ? 1 : 0) != 0;
}

int
PreferencesApp::GetIntPreference(const char *key, int defaultValue)
{
    return swGetIntPreference(_prefs, key, defaultValue);
}

const char *
PreferencesApp::GetPreference(const char *key, const char *defaultValue)
{
    return swGetPreference(_prefs, key, defaultValue);
}

void
PreferencesApp::SetBoolPreference(const char *key, bool value)
{
    swSetIntPreference(_prefs, key, value ? 1 : 0);
}

void
PreferencesApp::SetIntPreference(const char *key, int value)
{
    swSetIntPreference(_prefs, key, value);
}

void
PreferencesApp::SetPreference(const char *key, const char *value)
{
    swSetPreference(_prefs, key, value);
}

void PreferencesApp::unInstall(void)
{
    swUninstall(_prefs, COMPANY_NAME, APP_NAME);
#ifdef HAVE_UNINSTALL_COMMENT
    printf("%s\n", HAVE_UNINSTALL_COMMENT);
#endif
}
