/*
 * client/VideoMenu.cc:
 *
 * Copyright (C) 2000 John Watson, jwatson@tempusmud.com
 * 
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

#include "VideoMenu.h"

#include "../widgets/Widget.h"
#include "../widgets/LabelWidget.h"
#include "../widgets/ScrollpaneWidget.h"
#include "../widgets/ButtonWidget.h"
#include "../widgets/TableWidget.h"
#include "../widgets/DefaultTableModel.h"
#include "../widgets/SliderWidget.h"
#include "ClientState.h"
#include "../GraphicsState.h"

VideoMenu::VideoMenu( int w, int h, Client::State escape, Client::State close )
        : GenericScreen( w, h, escape, close ) 
{
        char buf[256];

        _name = "VideoMenu";

        _label = new LabelWidget( 256, 32, "Video Settings" );
        _label->setOpaque( true );

        addCenter( _label,  h - _label->getHeight() );

        // setup screen size stuff
        
        _sizeLabel = new LabelWidget( 192, 32, "Screen Size" );
        _sizeLabel->setOpaque( true );

        add( _sizeLabel, 0, _label->getY() - _sizeLabel->getHeight() - 8 );
        
        _sizeSlider = new SliderWidget( w - 320, 32,
                                        SLIDER_HORIZONTAL,
                                        9,
                                        1,
                                        cl_state.screen_size - 1);
        
        _sizeSlider->setOpaque( true );
        
        add( _sizeSlider, 
             _sizeLabel->getRight(), _sizeLabel->getY() );
        
        sprintf( buf, "%d", cl_state.screen_size );
        _sizeField = new LabelWidget( 128, 32, buf );
        _sizeField->setOpaque( true );
        
        add( _sizeField,
             _sizeSlider->getRight(), _sizeSlider->getY() );

        
        // setup fov stuff
        
        _fovLabel = new LabelWidget( 192, 32, "Field of View" );
        _fovLabel->setOpaque( true );

        add( _fovLabel, 0, _sizeLabel->getY() - _fovLabel->getHeight() - 8 );
        
        _fovSlider = new SliderWidget( w - 320, 32,
                                       SLIDER_HORIZONTAL,
                                       36,
                                       6,
                                       cl_state.fov / 5 );
        
        _fovSlider->setOpaque( true );
        
        add( _fovSlider, 
             _fovLabel->getRight(), _fovLabel->getY() );
        
        sprintf( buf, "%d", (int) cl_state.fov );
        _fovField = new LabelWidget( 128, 32, buf );
        _fovField->setOpaque( true );
        
        add( _fovField,
             _fovSlider->getRight(), _fovSlider->getY() );
        
        // checkbox toggles

        const int NUM_CHECKS = 10;
        
        const int CHECK_HEIGHT = 24;

        _checkLabels = new LabelWidget * [ NUM_CHECKS ];
        
        _checkLabels[0] = new LabelWidget( 192, CHECK_HEIGHT, "Texturing" );
        _checkLabels[1] = new LabelWidget( 192, CHECK_HEIGHT, "Lightmapping" );
        _checkLabels[2] = new LabelWidget( 192, CHECK_HEIGHT, "Dynamic Lights" );
        _checkLabels[3] = new LabelWidget( 192, CHECK_HEIGHT, "Wireframe" );
        _checkLabels[4] = new LabelWidget( 192, CHECK_HEIGHT, "Show Bounding" );
        _checkLabels[5] = new LabelWidget( 192, CHECK_HEIGHT, "PVS" );
        
        _checkLabels[6] = new LabelWidget( 192, CHECK_HEIGHT, "Multitex" );
        _checkLabels[7] = new LabelWidget( 192, CHECK_HEIGHT, "CVA" );
        
        _checkLabels[8] = new LabelWidget( 192, CHECK_HEIGHT, "Draw Walls" );
        _checkLabels[9] = new LabelWidget( 192, CHECK_HEIGHT, "Draw Floor/Ceil" );
        
        _checkButtons = new ButtonWidget * [ NUM_CHECKS ];

        for ( int i = 0; i < NUM_CHECKS; ++i ) {
                _checkButtons[i] = new ButtonWidget( 32, CHECK_HEIGHT );
                _checkButtons[i]->setCheckbox( true );
                _checkButtons[i]->addWidgetEventListener( this );
        }

        updateValues();

        _checkPanel = new Widget( 224, CHECK_HEIGHT * NUM_CHECKS );
        _checkPanel->setOpaque( true );

        for ( int i = 0; i < NUM_CHECKS; ++i ) {
                _checkPanel->add( _checkLabels[i], 0, _checkPanel->getHeight() - ( i + 1 ) * CHECK_HEIGHT );
                _checkPanel->add( _checkButtons[i], _checkLabels[i]->getRight(), _checkLabels[i]->getY() );
        }
        
        //        _checkScroll = new ScrollpaneWidget( _checkPanel->getWidth(), 256, _checkPanel );
        
        _optionsLabel = new LabelWidget( 192, 32, "Options" );
        _optionsLabel->setOpaque( true );

        addCenter( _optionsLabel, _fovLabel->getY() - _optionsLabel->getHeight() - 8 );
        
        addCenter( _checkPanel, _optionsLabel->getY() - _checkPanel->getHeight() - 8 );

        // back button
        
        _backButton = new ButtonWidget( 128, 32, "Back" );
        _backButton->setOpaque( true );
        
        addCenter( _backButton, 16 );

        _sizeSlider->addWidgetEventListener( this );
        _fovSlider->addWidgetEventListener( this );
        _backButton->addWidgetEventListener( this );
        acceptEventType( EVENT_ACTION, true );
        
}

VideoMenu::~VideoMenu() {
}

void VideoMenu::handleEvent( const class WidgetEvent * evt ) {

        char buf[128];
        
        if ( evt->getSource() == _sizeSlider ) {
                cl_state.screen_size = _sizeSlider->getValue() + 1;
                sprintf( buf, "%d", cl_state.screen_size );
                _sizeField->setText( buf );
        }
        
        else if ( evt->getSource() == _fovSlider ) {
                cl_state.fov = _fovSlider->getValue() * 5;
                sprintf( buf, "%d", (int) cl_state.fov );
                _fovField->setText( buf );
        }
        else if ( evt->getSource() == _checkButtons[0] ) {
                cl_state.use_textures = _checkButtons[0]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[1] ) {
                cl_state.use_lightmaps = _checkButtons[1]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[2] ) {
                cl_state.use_dynlights = _checkButtons[2]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[3] ) {
                cl_state.use_wireframe = _checkButtons[3]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[4] ) {
                cl_state.show_bounding = _checkButtons[4]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[5] ) {
                cl_state.use_pvs = _checkButtons[5]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[7] ) {
                if ( g_state.has_cva )
                        g_state.use_multitex = _checkButtons[7]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[8] ) {
                cl_state.draw_walls = _checkButtons[8]->isSelected();
        }
        else if ( evt->getSource() == _checkButtons[9] ) {
                cl_state.draw_floors = _checkButtons[9]->isSelected();
        }
        else if ( evt->getSource() == _backButton ) {
                doEscapeAction();
        }
}

void VideoMenu::updateValues() {
        _checkButtons[0]->setSelected( cl_state.use_textures );
        _checkButtons[1]->setSelected( cl_state.use_lightmaps );
        _checkButtons[2]->setSelected( cl_state.use_dynlights );
        _checkButtons[3]->setSelected( cl_state.use_wireframe );
        _checkButtons[4]->setSelected( cl_state.show_bounding );
        _checkButtons[5]->setSelected( cl_state.use_pvs );
        _sizeSlider->setValue( cl_state.screen_size - 1 );
        _fovSlider->setValue( cl_state.fov / 5 );
        
        
        _checkButtons[6]->setSelected( g_state.use_multitex );
        _checkButtons[6]->setEnabled(  false );
        _checkLabels[6]->setEnabled(  false );
        _checkLabels[6]->setOpaque( true );
        _checkButtons[7]->setSelected( g_state.use_cva );
        _checkButtons[7]->setEnabled(  g_state.has_cva );
        _checkLabels[7]->setEnabled(  g_state.has_cva );

        if ( g_state.has_cva == false )
                _checkLabels[7]->setOpaque( true );

        _checkButtons[8]->setSelected( cl_state.draw_walls );
        _checkButtons[9]->setSelected( cl_state.draw_floors );
        
}
