/*
 Copyright (C) 2002 Andreas Thiede ( a.thiede@berlin.de )

 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
 */

#import <Cocoa/Cocoa.h>
#include <QuickTime/QuickTime.h>

#import <app/PreferencesController.h>
#import <lib/settings.h>

#import <lib/bt848.h>
#import <lib/settings.h>
#import <lib/tvcards.h>
#import <lib/Tuner.h>
#import <lib/Preferences.h>

extern SETTING * BT848_GetSettingByName( const char * name );

extern const TVCARDSETUP  TVCards[];
extern const TVTUNERSETUP Tuners[];
extern const TTVFORMAT    TVFormats[];

static CodecNameSpecListPtr codecList;

static char * PToCStr( ConstStr255Param pstr, char *cstr)
{
    short       i, len;
    
    for (i=0, len= *pstr; i< len; i++) *(cstr+i) = *(pstr+i+1);
    *(cstr+len) = 0;
    return (cstr);
}

@implementation PreferencesController

-(id) init
{
    [super init];

    if( ! [ NSBundle loadNibNamed:@"Preferences" owner:self ] ) {
        return nil;
    }
    
    mInited = false;
    
    
    return self;
}

+ (void)show
{
    static controller = nil;

    if (!controller) {
        controller = [[PreferencesController alloc] init];
    }
    if (controller) {
        [controller showWindow:self];
    }
}

-(void) initSlider:(NSSlider*) slider iniSection:(const char*) iniSection iniName:(const char *) iniName
{
    SETTING * s;
    int       val;
    
    //NSLog( @"initSlider %s %p", iniName, slider );
    
    s = BT848_GetSettingByName( iniName );
    
    if( s != 0 ) {

        //NSLog( @"initSlider %s found setting", iniName);
    
        [ slider setMinValue: s->MinValue  ];
        [ slider setMaxValue: s->MaxValue  ];
        
        [ slider setFloatValue: (float)s->Default ];
        
        val = GetPrivateProfileInt( iniSection, iniName, s->Default );

        //NSLog( @"initSlider %s found userDefault", iniName);
        
        if( val >= s->MinValue && val < s->MaxValue ) {
            [ slider setFloatValue: (float)val ];
        }        
    }

    //NSLog( @"initSlider %s done", iniName );

}

-(void) onSliderChange:(NSSlider*) slider iniSection:(const char*) iniSection iniName:(const char *) iniName
{
    double val = [ slider floatValue ];
 
    WritePrivateProfileInt( iniSection, iniName , (int) val );    
}

-(void) setDefault:(NSSlider*) slider iniSection:(const char*) iniSection iniName:(const char *) iniName
{
    SETTING * s = BT848_GetSettingByName( iniName );

    if( s != 0 ) {

        WritePrivateProfileInt( iniSection, iniName , (int) s->Default );
    
        [ self initSlider:slider iniSection:iniSection iniName:iniName ];
    }
}

-(void) beforeFirstShow
{
    if( ! mInited ) {

        char result[1024];
    
        int i, s, val;
    
    
        [ self initSlider:mHue         iniSection:"Hardware" iniName:"InitialHue"         ];
        [ self initSlider:mSaturationV iniSection:"Hardware" iniName:"InitialSaturationV" ];
        [ self initSlider:mSaturationU iniSection:"Hardware" iniName:"InitialSaturationU" ];
        [ self initSlider:mContrast    iniSection:"Hardware" iniName:"InitialContrast"    ];
        [ self initSlider:mBrightness  iniSection:"Hardware" iniName:"InitialBrightness"  ];
        
        val = GetPrivateProfileInt( "Sound", "Volume", 50 );

        [ mVolume setFloatValue: (float)val ];

        val = GetPrivateProfileInt( "Sound", "Balance", 50 );

        [ mBalance setFloatValue: (float)val ];

        [ self onVolumeChange:self ];	

        [ mCard removeAllItems ];
    
        for( i = 0; i < TVCARD_LASTONE; i++ ) {
        
            const char * cardName = TVCards[i].szName;
        
            [ mCard addItemWithTitle: [NSString stringWithCString: cardName ] ];
        }

        [ mTuner removeAllItems ];

        for( i = 0; i < TUNER_LASTONE; i++ ) {
        
            const char * tunerName = Tuners[i].szName;
        
            [ mTuner addItemWithTitle: [NSString stringWithCString: tunerName ] ];
        }

        [ mFormat removeAllItems ];

        for( i = 0; i < FORMAT_LASTONE; i++ ) {
        
            const char * formatName = TVFormats[i].szDesc;
        
            [ mFormat addItemWithTitle: [NSString stringWithCString: formatName ] ];
        }
        
        s = GetPrivateProfileInt( "Hardware", "CardType", 0 );
        
        if( s >= 0 && s < TVCARD_LASTONE ) {
            [ mCard selectItemAtIndex: s ];
        }

        s = GetPrivateProfileInt( "Hardware", "TunerType", 0 );
        
        if( s >= 0 && s < TUNER_LASTONE ) {
            [ mTuner selectItemAtIndex: s ];
        }

        s = GetPrivateProfileInt( "Hardware", "TVType", 0 );
        
        if( s >= 0 && s < FORMAT_LASTONE ) {
            [ mFormat selectItemAtIndex: s ];
        }

        [ mVideoSource removeAllItems ];
        
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "Tuner"                 ]];
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "Composite"             ]];
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "SVideo"                ]];
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "Other 1"               ]];
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "Other 2"               ]];
        [ mVideoSource addItemWithTitle: [NSString stringWithCString: "Composite via SVideo " ]];

        s = GetPrivateProfileInt( "Hardware", "VideoSource", 0 );
        
        if( s >= 0 && s < 6 ) {
            [ mVideoSource selectItemAtIndex: s ];
        }

        [ mAudioSource removeAllItems ];
        
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "Tuner"    ]];
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "Radio"    ]];
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "External" ]];
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "Internal" ]];
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "Mute"     ]];
        [ mAudioSource addItemWithTitle: [NSString stringWithCString: "Stereo"   ]];
        
        s = GetPrivateProfileInt( "Sound", "AudioSource", 0 );
        
        if( s >= 0 && s < 6 ) {
            [ mAudioSource selectItemAtIndex: s ];
        }

        [ mAudioOutput removeAllItems ];

        {
            int nAudioOutputs = GetPrivateProfileInt( "Sound", "NumberAudioOutputDevices", 0 );
        
            for( i = 0; i < nAudioOutputs; i++ ) {
                    
                char name  [128];
            
                sprintf( name, "AudioOutputDevice%d", i );
            
                GetPrivateProfileString( "Sound", name, "", result, sizeof(result) );
        
                if( result[0] != 0 ) {
            
                    [ mAudioOutput addItemWithTitle: [NSString stringWithCString: result ] ];
                }
            }

            GetPrivateProfileString( "Sound", "AudioOutput", "none", result, sizeof(result) );
        
            [ mAudioOutput selectItemWithTitle: [NSString stringWithCString: result ] ];
            
        }
        
        [ mAudioInput removeAllItems ];


        {
            int nAudioInputs = GetPrivateProfileInt( "Sound", "NumberAudioInputDevices", 0 );
        
            for( i = 0; i < nAudioInputs; i++ ) {
                    
                char name  [128];
            
                sprintf( name, "AudioInputDevice%d", i );
            
                GetPrivateProfileString( "Sound", name, "name", result, sizeof(result) );
        
                if( result[0] != 0 ) {
            
                    [ mAudioInput addItemWithTitle: [NSString stringWithCString: result ] ];
                }
            }
        
            GetPrivateProfileString( "Sound", "AudioInput", "none", result, sizeof(result) );
        
            [ mAudioInput selectItemWithTitle: [NSString stringWithCString: result ] ];
        }
        
        GetPrivateProfileString( "Recording", "Prefix", "movie", result, sizeof(result) );

        [ mRecordingPrefix setStringValue: [NSString stringWithCString: result ] ];

        GetPrivateProfileString( "Recording", "Directory", "/tmp", result, sizeof(result) );

        [ mRecordingDir setStringValue: [NSString stringWithCString: result ] ];


        val = GetPrivateProfileInt( "Recording", "UseVideo" , 1  );

        [ mRecordVideo setIntValue:val ];
        
        val = GetPrivateProfileInt( "Recording", "UseAudio" , 1  );

        [ mRecordAudio setIntValue:val ];

        val = GetPrivateProfileInt( "Recording", "ScaleDivider", 4 );

        [ mRecordingScale setFloatValue: 100 / (float)val ];

        {
            int index = -1;
            
            s = GetPrivateProfileInt( "Recording", "Compression", 0 );

            [ mCompression removeAllItems ];
    
            if( GetCodecNameList ( &codecList, 1 ) == noErr ) {
                
                int i;
                
                for( i = 0; i< codecList->count; i++ ) {
        
                    char buf[256];
                    
                    CodecNameSpec p = codecList->list[i];

                    [ mCompression addItemWithTitle: [NSString stringWithCString: PToCStr( p.typeName, buf ) ] ];

                    //printf("added %s type %d\n",  PToCStr( p.typeName, buf ), p.cType );
                    
                    if( s == p.cType ) {

                        //printf("selected %s type %d\n",  PToCStr( p.typeName, buf ), p.cType );
                        
                        index = i;
                    }
                }
            }

            if( index >= 0 ) {

                [ mCompression selectItemAtIndex: index ];
            }
        }

        s = GetPrivateProfileInt( "Window", "StayOnTop", 0 );
        
        [ mStayOnTop setIntValue: s ];
 
        {
            int i;
            
            int maxCountries = sizeof(Countries) / sizeof( TCountries);
            
            int country = GetPrivateProfileInt( "Hardware", "Country", 0 );
        
            Load_Country_Settings( [[[NSBundle mainBundle] pathForResource:@"Channel" ofType:@"txt"] cString] );

            [ mCountry removeAllItems ];
            
            for( i = 0; i < maxCountries; i++ ) {

                if( Countries[i].Name[0] != 0 ) {

                    [ mCountry addItemWithTitle: [ NSString stringWithCString: Countries[i].Name ] ];
                    
                }
            }

            if( country >= 0 && country < maxCountries ) {

                [ mCountry selectItemAtIndex: country ];
            }
            // mod philipp here
            [ mOpenGL removeAllItems ];
        
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "default"               ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "Generic"             ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "AppleSW"                ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "ATIRage128"               ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "ATIRagePro"               ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "ATIRadeon"               ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "GeForce2MX" ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "GeForce3" ]];
            [ mOpenGL addItemWithTitle: [NSString stringWithCString: "Mesa3DFX" ]];
        
            s = GetPrivateProfileInt( "Window", "OpenGL", 0 );
        
            if( s >= 0 && s < 9 ) {
                [ mOpenGL selectItemAtIndex: s ];
            }
        }
        mInited = true;
    }
}

- (IBAction) onDefault:(id)sender
{
    [ self setDefault:mHue            iniSection:"Hardware"  iniName:"InitialHue"         ];
    [ self setDefault:mSaturationV    iniSection:"Hardware"  iniName:"InitialSaturationV" ];
    [ self setDefault:mSaturationU    iniSection:"Hardware"  iniName:"InitialSaturationU" ];
    [ self setDefault:mContrast       iniSection:"Hardware"  iniName:"InitialContrast"    ];
    [ self setDefault:mBrightness     iniSection:"Hardware"  iniName:"InitialBrightness"  ];
    [ self setDefault:mRecordingScale iniSection:"Recording" iniName:"ScaleDivider"       ];


    [ mVolume  setFloatValue: 50.0 ];
    [ mBalance setFloatValue: 50.0 ];

    [ self onVolumeChange:self ];	

}

- (IBAction) onCardChange:(id)sender
{
    int val = [ mCard indexOfSelectedItem ];

    //NSLog( @"PreferencesController.onCardChange %d", val );
    
    if( val >= 0 && val < TVCARD_LASTONE ) {
 
        WritePrivateProfileInt( "Hardware", "CardType" , val );
    }
}

- (IBAction) onTunerChange:(id)sender
{
    int val = [ mTuner indexOfSelectedItem ];

    //NSLog( @"PreferencesController.onTunerChange %d", val );    
        
    if( val >= 0 && val < TUNER_LASTONE ) {
 
        [ self onVideoSourceChange:sender ];

        WritePrivateProfileInt( "Hardware", "TunerType" , val );
    }
}

- (IBAction) onFormatChange:(id)sender
{
    int val = [ mFormat indexOfSelectedItem ];
    
    //NSLog( @"PreferencesController.onFormatChange %d", val );
        
    if( val >= 0 && val < FORMAT_LASTONE ) {
 
        WritePrivateProfileInt( "Hardware", "TVType" , val );        
    }
}

- (IBAction) onHueChange:(id)sender
{
    //NSLog( @"PreferencesController.onHueChange" );

    [ self onSliderChange:mHue iniSection:"Hardware" iniName:"InitialHue" ];

}

- (IBAction) onSaturationChangeV:(id)sender
{
    //NSLog( @"PreferencesController.onSaturationChangeV" );
    
    [ self onSliderChange:mSaturationV iniSection:"Hardware" iniName:"InitialSaturationV" ];

}

- (IBAction) onSaturationChangeU:(id)sender
{
    //NSLog( @"PreferencesController.onSaturationChangeU" );

    [ self onSliderChange:mSaturationU iniSection:"Hardware" iniName:"InitialSaturationV" ];

}

- (IBAction) onContrastChange:(id)sender
{
    ////NSLog( @"PreferencesController.onContrastChange" );
    
    [ self onSliderChange:mContrast iniSection:"Hardware" iniName:"InitialContrast" ];
}

- (IBAction) onBrightnessChange:(id)sender
{
    double val = [ mBrightness floatValue ];

    NSLog( @"PreferencesController.onBrightnessChange %e", val );
    
    [ self onSliderChange:mBrightness iniSection:"Hardware" iniName:"InitialBrightness" ];

}

- (IBAction) onAudioSourceChange:(id)sender
{
    int val = [ mAudioSource indexOfSelectedItem ];

    //NSLog( @"PreferencesController.onAudioSourceChange %d", val );
    
    if( val >= 0 && val < 6 ) {
 
        WritePrivateProfileInt( "Sound", "AudioSource" , val );
   }
}

- (IBAction) onVideoSourceChange:(id)sender
{
    int val = [ mVideoSource indexOfSelectedItem ];

    //NSLog( @"PreferencesController.onVideoChange %d", val );
    
    if( val >= 0 && val < 6 ) {
 
        WritePrivateProfileInt( "Hardware", "VideoSource" , val );
   }
}

- (IBAction) onVolumeChange:(id)sender
{
    float vol = [ mVolume  floatValue ];
    float bal = [ mBalance floatValue ];

    //NSLog( @"PreferencesController.onVolumeChange %f", vol );
    
    WritePrivateProfileInt( "Sound", "Volume" ,  (int) vol );
    WritePrivateProfileInt( "Sound", "Balance" , (int) bal );

}

- (IBAction) onBalanceChange:(id)sender
{
    float val = [ mBalance floatValue ];

    //NSLog( @"PreferencesController.onBalanceChange %f", val  );

    [ self onVolumeChange:sender ];
}

- (IBAction) onAudioOutputChange:(id)sender
{
    NSString * val = [ mAudioOutput titleOfSelectedItem ];

    //NSLog( @"PreferencesController.onAudioOutputChange %s", [ val cString ] );
    
    WritePrivateProfileString( "Sound", "AudioOutput" , [ val cString ] );
}

- (IBAction) onAudioInputChange:(id)sender
{
    NSString * val = [ mAudioInput titleOfSelectedItem ];

    //NSLog( @"PreferencesController.onAudioInputChange %s", [ val cString ] );
    
    WritePrivateProfileString( "Sound", "AudioInput" , [ val cString ] );
}

- (IBAction) onRecordingScaleChange:(id)sender
{
    int scale;
    int val = [ mRecordingScale floatValue ];

    //printf( "PreferencesController.onRecordingScaleChange %d", val );
    
    
    switch( val ) {
    case 100:
        scale = 1;
        break;
    case 50:
        scale = 2;
        break;
    default:
        scale = 4;
        break;
    }
    
    WritePrivateProfileInt( "Recording", "ScaleDivider" , scale );

}

- (IBAction) onFrameRateChange:(id)sender
{
    float val = [ mFrameRate floatValue ];

    char buf[24];
    
    sprintf( buf, "%f", val );
    
    WritePrivateProfileString( "Recording", "FrameRate" , buf  );
}

- (IBAction) onCompressionChange:(id)sender
{
    int val = [ mCompression indexOfSelectedItem ];
    
    if( val >= 0 & val < codecList->count ) {

        char buf[256];
        
        CodecNameSpec p = codecList->list[val];
                    
        //printf("selected %s type %d\n",  PToCStr( p.typeName, buf ), p.cType );
            
        WritePrivateProfileInt( "Recording", "Compression" , p.cType  );
            
    }        
}

- (IBAction) onStayOnTopChange:(id)sender
{
    int val = [ mStayOnTop intValue ];

    WritePrivateProfileInt( "Window", "StayOnTop" , val  );
}

- (IBAction) onSetRecordingPrefix:(id)sender
{
    NSString * val = [ mRecordingPrefix stringValue ];

    WritePrivateProfileString( "Recording", "Prefix" , [ val cString ]  );
}

- (IBAction) onSetRecordingDirNav:(id)sender
{
    int result;

    NSArray * fileTypes = [NSArray arrayWithObject:@"*"];
    
    NSOpenPanel * oPanel = [NSOpenPanel openPanel];

    [ oPanel setAllowsMultipleSelection:NO];
    [ oPanel setCanChooseFiles:NO ];
    [ oPanel setCanChooseDirectories:YES ];
    [ oPanel setResolvesAliases:NO ];
    
    result = [oPanel runModalForDirectory:NSHomeDirectory() file:nil types:fileTypes];

    if( result == NSOKButton ) {
    
        NSArray * filesToOpen = [oPanel filenames];
                
        NSString * aFile = [ filesToOpen objectAtIndex:0 ];

        [ mRecordingDir setStringValue: aFile ];
        
        [ self onSetRecordingDirEdit:sender ];
    }
}


- (IBAction) onSetRecordingDirEdit:(id)sender
{
    NSString * val = [ mRecordingDir stringValue ];

    WritePrivateProfileString( "Recording", "Directory" , [ val cString ]  );
}

- (IBAction) onRecordAudioChange:(id)sender
{
    int val = [ mRecordAudio intValue ];

    WritePrivateProfileInt( "Recording", "UseAudio" , val  );
}

- (IBAction) onRecordVideoChange:(id)sender
{
    int val = [ mRecordVideo intValue ];

    WritePrivateProfileInt( "Recording", "UseVideo" , val  );
}

- (IBAction) onCountryChange:(id)sender
{
    int val = [ mCountry indexOfSelectedItem ];

    WritePrivateProfileInt( "Hardware", "Country" , val  );
}
// mod philipp here
- (IBAction) onOpenGL:(id)sender
{

    int val = [ mOpenGL indexOfSelectedItem ];

    WritePrivateProfileInt( "Window", "OpenGL" , val  );

}



- (IBAction) showWindow:(id)sender
{
    if (!mInited) {
        [ self beforeFirstShow ];
    }
    
    [ mWindow center ];
    [ mWindow makeKeyAndOrderFront:self ];

}

- (IBAction) hideWindow:(id)sender
{
    [ mWindow orderOut:self ];
}

- (NSQuickDrawView*) qdView;
{
    return mVideoView;
}

@end


