/*
    DAAC_UIController.m

    Copyright 2008,2009 Josh Freeman
    http://www.twilightedge.com

    This file is part of DAA Converter v1.3 for Mac OS X.

    DAA Converter 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, see <http://www.gnu.org/licenses/>.
*/

#import "DAAC_UIController.h"

#import "DAAC_FilenameUtilities.h"
#import "DAAC_Strings.h"


#define kMainWindowIdentifier                       @"mainWindow"

#define kAboutPanelCreditsFontName                  @"Monaco"
#define kAboutPanelCreditsFontSize                  12
#define kAboutPanelCreditsFontColor                 [NSColor colorWithCalibratedRed: 0.25   \
                                                                              green: 0.35   \
                                                                               blue: 0.0    \
                                                                              alpha: 1.0]
#define kAboutPanelCreditsIndentString              @"   "


typedef enum
{
    kMainWindowMode_DefaultState = 0,
    kMainWindowMode_SelectingFilesToConvert,
    kMainWindowMode_ConvertingFile

} MainWindowMode;


@interface DAAC_UIController (PrivateMethods)

- (void) setMainWindowMode: (MainWindowMode) mainWindowMode;

- (void) updateMainWindowTitleForConversion;

- (void) openPanelDidEnd: (NSOpenPanel *) panel
                returnCode: (int) returnCode
                contextInfo: (void  *) contextInfo;

- (void) errorSheetDidEnd: (NSWindow *) sheet
            returnCode: (int) returnCode
            contextInfo: (void *) contextInfo;

- (void) notifyDelegateDidSelectFilesToConvert: (NSArray *) filesToConvert;
- (void) notifyDelegateDidReceivePassword: (NSString *) password;
- (void) notifyDelegateDidReceiveCancel;
- (void) notifyDelegateDidFinishDisplayingErrorMessage;
- (void) getConversionToolCreditsFromDelegate: (NSString **) returnedToolCredits;

@end

@implementation DAAC_UIController

- (void) awakeFromNib
{
    _mainWindowFixedHeight = [_mainWindow maxSize].height;

    [_mainWindow setDelegate: self];

    [_mainWindow setFrameUsingName: kMainWindowIdentifier];

    [self setMainWindowMode: kMainWindowMode_DefaultState];

    [_mainWindow makeKeyAndOrderFront: self];
}

- (void) dealloc
{
    [_mainWindow setDelegate: nil];

    [_conversionSourceFilename release];
    [_conversionTargetFilename release];

    [super dealloc];
}

#pragma mark Main Window

- (void) setMainWindowMode: (MainWindowMode) mainWindowMode
{
    _mainWindowMode = mainWindowMode;

    switch (mainWindowMode)
    {
        case kMainWindowMode_ConvertingFile:
            [self updateMainWindowTitleForConversion];
        break;

        case kMainWindowMode_SelectingFilesToConvert:
            [_mainWindow setTitle: kUIString_MainWindowTitle_SelectingFilesToConvert];
        break;

        case kMainWindowMode_DefaultState:
        default:
            _mainWindowMode = kMainWindowMode_DefaultState;
            [_mainWindow setTitle: kUIString_MainWindowTitle_Default];
        break;
    }

    if (_mainWindowMode == kMainWindowMode_ConvertingFile)
    {
        [_mainWindowConversionStatusTextField setHidden: NO];
        [_mainWindowConversionProgressIndicator setHidden: NO];
        [_mainWindowCancelButton setEnabled: YES];
    }
    else
    {
        [_mainWindowConversionStatusTextField setHidden: YES];
        [_mainWindowConversionProgressIndicator setHidden: YES];
        [_mainWindowCancelButton setEnabled: NO];
    }
}

- (IBAction) mainWindowCancelButtonPressed: (id) sender;
{
    [self notifyDelegateDidReceiveCancel];
}

#pragma mark NSWindow Delegate Methods

- (NSSize) windowWillResize: (NSWindow *) sender toSize: (NSSize) frameSize
{
    if (frameSize.height != _mainWindowFixedHeight)
        frameSize.height = _mainWindowFixedHeight;

    return frameSize;
}

- (void) windowDidResize: (NSNotification *) notification
{
    [_mainWindow saveFrameUsingName: kMainWindowIdentifier];
}

- (void) windowDidMove: (NSNotification *) notification
{
    [_mainWindow saveFrameUsingName: kMainWindowIdentifier];
}

#pragma mark Selecting Files To Convert

- (void) promptForFilesToConvert
{
    NSOpenPanel *openPanel;

    [self setMainWindowMode: kMainWindowMode_SelectingFilesToConvert];

    openPanel = [NSOpenPanel openPanel];

    [openPanel setAllowsMultipleSelection: YES];

    [openPanel beginSheetForDirectory: nil
                            file: nil
                            types: DAAFileExtensions()
                            modalForWindow: _mainWindow
                            modalDelegate: self
                            didEndSelector: @selector(openPanelDidEnd:returnCode:contextInfo:)
                            contextInfo: nil];
}

- (void) openPanelDidEnd: (NSOpenPanel *) panel
                returnCode: (int) returnCode
                contextInfo: (void  *) contextInfo
{
    [[NSApplication sharedApplication] endSheet: panel];
    [panel orderOut: self];

    [self setMainWindowMode: kMainWindowMode_DefaultState];

    if (returnCode == NSOKButton)
        [self notifyDelegateDidSelectFilesToConvert: [panel filenames]];
    else
        [self notifyDelegateDidReceiveCancel];
}

#pragma mark Converting File

- (bool) setupForNewConversionWithTargetFilename: (NSString *) targetFilename
                                conversionNumber: (unsigned) conversionNumber
{
    if (!targetFilename)
        goto ERROR;

    [_conversionTargetFilename release];
    _conversionTargetFilename = [targetFilename retain];

    _conversionNumber = conversionNumber;

    [self updateConversionSourceFilename: nil];
    [self updateConversionProgress: 0];

    [self setMainWindowMode: kMainWindowMode_ConvertingFile];

    return YES;

ERROR:
    return NO;
}

- (void) updateMainWindowTitleForConversion
{
    NSString *newMainWindowTitle;

    if (_mainWindowMode != kMainWindowMode_ConvertingFile)
        return;

    if (!_conversionTargetFilename)
        goto ERROR;

    if (_totalNumberOfConversions > 1)
    {
        newMainWindowTitle =
            [NSString stringWithFormat: kUIString_MainWindowTitle_MultipleConversionTemplate,
                                        _conversionTargetFilename,
                                        _conversionNumber,
                                        _totalNumberOfConversions];
    }
    else
    {
        newMainWindowTitle =
            [NSString stringWithFormat: kUIString_MainWindowTitle_SingleConversionTemplate,
                                        _conversionTargetFilename];
    }

    if (!newMainWindowTitle)
        goto ERROR;

    [_mainWindow setTitle: newMainWindowTitle];

    return;

ERROR:
    [_mainWindow setTitle: kUIString_MainWindowTitle_Default];
}

- (void) updateConversionProgress: (unsigned) completionPercentage
{
    [_mainWindowConversionProgressIndicator setDoubleValue: (double) completionPercentage];
}

- (void) updateConversionSourceFilename: (NSString *) sourceFilename
{
    NSString *newConversionStatusString = nil;

    [_conversionSourceFilename release];
    _conversionSourceFilename = [sourceFilename retain];

    if (_conversionSourceFilename)
    {
        newConversionStatusString =
                    [NSString stringWithFormat: kUIString_MainWindowConversionSourceTemplate,
                                                _conversionSourceFilename];
    }

    if (!newConversionStatusString)
        newConversionStatusString = @" ";

    [_mainWindowConversionStatusTextField setStringValue: newConversionStatusString];
}

- (void) updateTotalNumberOfConversions: (unsigned) totalNumConversions
{
    _totalNumberOfConversions = totalNumConversions;

    if (_mainWindowMode == kMainWindowMode_ConvertingFile)
        [self updateMainWindowTitleForConversion];
}

#pragma mark Error Message

- (void) displayErrorMessage: (NSString *) errorMessage
{
    NSString *errorFilename;

    if (!errorMessage)
        errorMessage = kErrorMessage_UnknownError;

    errorFilename = (_conversionSourceFilename) ? _conversionSourceFilename : @" ";

    NSBeginCriticalAlertSheet(errorFilename, kUIString_ErrorSheetOKButton, nil, nil,
                                _mainWindow, self,
                                @selector(errorSheetDidEnd:returnCode:contextInfo:), nil, nil,
                                errorMessage);
}

- (void) errorSheetDidEnd: (NSWindow *) sheet
            returnCode: (int) returnCode
            contextInfo: (void *) contextInfo
{
    [[NSApplication sharedApplication] endSheet: sheet];
    [sheet orderOut: self];

    [self notifyDelegateDidFinishDisplayingErrorMessage];
}

#pragma mark Password Prompt

- (void) promptForPassword
{
    int passwordPanelReturnCode;

    [_passwordPanelTextField setStringValue: @""];

    [NSApp beginSheet: _passwordPanel
        modalForWindow: _mainWindow
        modalDelegate: nil
        didEndSelector: nil
        contextInfo: nil];

    passwordPanelReturnCode = [NSApp runModalForWindow: _passwordPanel];

    [NSApp endSheet: _passwordPanel];
    [_passwordPanel orderOut: self];

    if (passwordPanelReturnCode == NSRunStoppedResponse)
    {
        [self notifyDelegateDidReceivePassword: [_passwordPanelTextField stringValue]];
    }
    else
    {
        [self notifyDelegateDidReceiveCancel];
    }
}

- (IBAction) passwordPanelButtonPressed: (id) sender
{
    if (sender == _passwordPanelOKButton)
        [NSApp stopModal];
    else
        [NSApp abortModal];
}

#pragma mark About Panel

- (IBAction) doAboutPanel: (id) sender
{
    static NSDictionary *aboutPanelOptions = nil;

    if (!aboutPanelOptions)
    {
        NSString *toolCredits;
        NSMutableString *allCredits;
        NSAttributedString *attributedAllCredits;
        NSDictionary *creditsAttributes;

        [self getConversionToolCreditsFromDelegate: &toolCredits];

        if (!toolCredits)
            toolCredits = @" ";

        allCredits = [NSMutableString stringWithFormat: @"%@%@\n%@",
                                                        kAboutPanelCreditsIndentString,
                                                        kUIString_AboutPanelAppCredits,
                                                        toolCredits];

        [allCredits replaceOccurrencesOfString: @"\n"
                                        withString: [NSString stringWithFormat: @"\n%@",
                                                                kAboutPanelCreditsIndentString]
                                        options: 0
                                        range: NSMakeRange(0, [allCredits length])];

        creditsAttributes = [NSDictionary dictionaryWithObjectsAndKeys:

                                            [NSFont fontWithName: kAboutPanelCreditsFontName
                                                        size: kAboutPanelCreditsFontSize],
                                                NSFontAttributeName,

                                            kAboutPanelCreditsFontColor,
                                                NSForegroundColorAttributeName,

                                            nil];

        if (allCredits && creditsAttributes)
        {
            attributedAllCredits = [[[NSAttributedString alloc] initWithString: allCredits
                                                                attributes: creditsAttributes]
                                            autorelease];

            if (attributedAllCredits)
            {
                aboutPanelOptions = [[NSDictionary dictionaryWithObject: attributedAllCredits
                                                                forKey: @"Credits"]
                                                retain];
            }
        }
    }

    [[NSApplication sharedApplication]
                                orderFrontStandardAboutPanelWithOptions: aboutPanelOptions];
}

#pragma mark Delegate Notifiers

- (void) notifyDelegateDidSelectFilesToConvert: (NSArray *) filesToConvert
{
    if ([_delegate respondsToSelector: @selector(uiControllerSelectedFilesToConvert:)])
        [_delegate uiControllerSelectedFilesToConvert: filesToConvert];
}

- (void) notifyDelegateDidReceivePassword: (NSString *) password
{
    if ([_delegate respondsToSelector: @selector(uiControllerReceivedPassword:)])
        [_delegate uiControllerReceivedPassword: password];
}

- (void) notifyDelegateDidReceiveCancel
{
    if ([_delegate respondsToSelector: @selector(uiControllerReceivedCancel)])
        [_delegate uiControllerReceivedCancel];
}

- (void) notifyDelegateDidFinishDisplayingErrorMessage
{
    if ([_delegate respondsToSelector: @selector(uiControllerFinishedDisplayingErrorMessage)])
        [_delegate uiControllerFinishedDisplayingErrorMessage];
}

- (void) getConversionToolCreditsFromDelegate: (NSString **) returnedToolCredits
{
    if ([_delegate respondsToSelector:
                                @selector(uiControllerNeedsConversionToolCreditsForAboutBox:)])
    {
        [_delegate uiControllerNeedsConversionToolCreditsForAboutBox: returnedToolCredits];
    }
}

@end
