#import <Cocoa/Cocoa.h>
#import "PreferencesController.h"
#import "Settings.h"
#import "tvcards.h"
#import "xtv.h"
#include <IO/Manager/IOManager.hpp>
#import <lib/Preferences.h>

extern "C" SETTING * BT848_GetSettingByName( const char * name );
extern "C" int       BT848_SetVideoSource( int );
extern "C" int       Audio_SetSource( int );
extern "C" int       TVCard_OnChange( int );
extern "C" int       TVTuner_OnChange( int );
extern "C" void      WritePrivateProfileInt(const char * section, const char * var, int value, const char *  szIniFile);
extern "C" int       TVFormat_OnChange(long NewValue);
extern "C" void      ChangeTVSettingsBasedOnTuner();

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

static string i2str( int val )
{
    char buf[32];
    
    sprintf( buf, "%d", val );
    
    return string(buf );
}

@implementation PreferencesController

-(id) init
{
    [super init];
    
    mInited = false;
    
    return self;
}

+(PreferencesController*) show
{
#if 0
    PreferencesController * prefs = [ PreferencesController alloc ];
    
    [ prefs initWithWindowNibName: [NSString stringWithCString: "xtv"] owner:[ NSApplication sharedApplication ] ];
    
    [ prefs loadWindow ];

    //[ prefs showWindow:[ NSApplication sharedApplication ] ];
    
    [ [ prefs window ] showWindwow: [ NSApplication sharedApplication ]];

    return prefs;
#else

    NSMenu * menu = [[ NSApplication sharedApplication ] mainMenu ];
    
    NSEvent * event = [ NSEvent keyEventWithType: NSKeyDown
                                location:[ NSEvent mouseLocation]
                                modifierFlags: NSCommandKeyMask
                                timestamp:0
                                windowNumber:0
                                context:nil
                                characters: [NSString stringWithCString:"p" ]
                                charactersIgnoringModifiers:[NSString stringWithCString:"p" ]
                                isARepeat:NO
                                keyCode:0 ];
	     
    [ menu performKeyEquivalent:event ];
    

    return 0;
#endif
}


-(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 setMaxValue: s->StepValue ];
        
        [ 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 ];
        }
        
        if( s->pfnOnChange ) {
            s->pfnOnChange( val );
        }
    }

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

}

-(void) onSliderChange:(NSSlider*) slider iniSection:(const char*) iniSection iniName:(const char *) iniName
{
    SETTING * s;
    double val = [ slider floatValue ];
 
    s = BT848_GetSettingByName( iniName );

    if( s != 0 ) {

        WritePrivateProfileInt( iniSection, iniName , (int) val, "" );
    
        if( s->pfnOnChange ) {
            s->pfnOnChange( (int)val );
        }
    }
}

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

    if( s != 0 ) {

        if( s->pValue ) {
            
            * s->pValue = s->Default;
            
            WritePrivateProfileInt( iniSection, iniName , (int) s->Default, "" );
    
            [ self initSlider:slider iniSection:iniSection iniName:iniName ];
        }
    }
}

-(void) beforeFirstShow
{
    if( ! mInited ) {
    
        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 ];
            TVFormat_OnChange( 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 ];
            BT848_SetVideoSource( 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 ];
            Audio_SetSource( s );
        }

        [ mAudioOutput removeAllItems ];

        for( i = 0; i < 2; i++ ) {
        
            const char * deviceName = "";//TVFormats[i].szDesc;
        
            [ mAudioOutput addItemWithTitle: [NSString stringWithCString: deviceName ] ];
        }

        s = GetPrivateProfileInt( "Sound", "AudioOutput", 0, "" );
        
        if( s >= 0 && s < 6 ) {
            [ mAudioOutput selectItemAtIndex: s ];
            //Audio_SetSource( 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"  ];


    [ 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 ) {
 
        TVCard_OnChange( val );
        
        WritePrivateProfileInt( "Hardware", "CardType" , val, "" );
    }
}

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

    NSLog( @"PreferencesController.onTunerChange %d", val );    
        
    if( val >= 0 && val < TUNER_LASTONE ) {
 
        TVTuner_OnChange( val );
             
        [ 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 ) {
 
        TVFormat_OnChange( val );
        
        WritePrivateProfileInt( "Hardware", "TVType" , val, "" );
        
        int w = 360,h;
        
        switch( val ) {
        case FORMAT_PAL_BDGHI:
        case FORMAT_SECAM:
        case FORMAT_PAL_N:
            w = 360;
            h = 288;
            break;
        case FORMAT_NTSC:

        case FORMAT_PAL_M:
        case FORMAT_PAL60:
        case FORMAT_NTSC_J:
            w = 360;
            h = 240;
            break;
        }

        IOManager::instance().sendCommand( "GLWindow", "setMovieSize",  i2str(w), i2str(h) );
        IOManager::instance().sendCommand( "GLWindow", "setWindowSize", i2str(w), i2str(h) );

    }
}

- (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
{
    NSLog( @"PreferencesController.onBrightnessChange" );
    
    [ 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 ) {
 
        Audio_SetSource(  val );
        
        WritePrivateProfileInt( "Sound", "AudioSource" , val, "" );
   }
}

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

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

- (IBAction) onVolumeChange:(id)sender
{
    float vol = [ mVolume  floatValue ];
    float bal = [ mBalance floatValue ];
    int l,r;
    
    WritePrivateProfileInt( "Sound", "Volume" ,  (int) vol, "" );
    WritePrivateProfileInt( "Sound", "Balance" , (int) bal, "" );

    r = (int) vol;
    l = (int) vol;
     
    if( bal > 50 ) {
        bal -= 50;
        bal *= 2;
        l = (int) (vol - bal);
        
        if( l < 0 )
            l = 0;
    }
    else if( bal < 50 ) {
        bal -= 50;
        bal *= 2;
        r = (int) (vol + bal);
        
        if( r < 0 ) 
            r = 0;
    }

    NSLog( @"PreferencesController.onVolumeChange val(%f) bal(%f) left(%d) right(%d)", vol, bal, l,r  );

    char r_str[32];
    char l_str[32];

    sprintf( l_str, "%d", l );
    sprintf( r_str, "%d", r );
    
    IOManager::instance().sendCommand( "LineOut", "leftVolume", l_str );
    IOManager::instance().sendCommand( "LineOut", "rightVolume", r_str );

    
}

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

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

    [ self onVolumeChange:sender ];
}

- (IBAction) onAudioOutputChange:(id)sender
{
    int val = [ mAudioOutput indexOfSelectedItem ];

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

- (IBAction) showWindow:(id)sender
{
    NSLog( @"PreferencesController.showWindow" );
    
    [ self beforeFirstShow ];
    
    [ super showWindow:sender ];

    //[ XTV setOutput:mVideoView ];

}

- (IBAction) hideWindow:(id)sender
{
    NSLog( @"PreferencesController.hideWindow" );
    
    [ self close ];
}

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

@end


