/*
        Shortcuts.m

	FullScreenWindow : This file is part of SlideShow

	Copyright (C) 2004 Fabien VALLON
	Additional copyrights here

	Authors: Fabien VALLON <fabien.vallon@fr.alcove.com>
	Date:	24 March 2004

	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:

		Free Software Foundation, Inc.
		59 Temple Place - Suite 330
		Boston, MA  02111-1307, USA
*/

#include "Shortcuts.h"

#include <Foundation/NSArray.h>
#include <Foundation/NSBundle.h>
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSString.h>


//TODO check some mem leaks 

//Shortcuts is implement as singleton
static Shortcuts *sharedShortcurts = nil;

//For slideshow user Library & defaults keybindings (resource)
static NSString *USERSLIDESHOWSHORTCUTS = @"SlideShow/KeyBinding.dict";
static NSString *RESOURCEDEFAULTSSLIDEKEYBINDINGS = @"DefaultSlideShowKeyBindings";

//Notification sent when synchronize
static NSString *SLIDESHOWSHORTCUTSNOTIFICATION = @"SLIDESHOWSHORTCUTSNOTIFICATION";

@interface Shortcuts (Private)
-(void) _initShortcuts;
@end

@implementation Shortcuts (Private)

/*
  Buid shortcuts dictionary from user KeyBinding.dict or (if not possible) 
  from SlideShow DefaultskeyBinding.dict ( see GNUMakefile Resource ).
 */
-(void) _initShortcuts 
{
  NSArray *paths;
  NSString *userLibPath;
  NSString *keybindingPath;
  BOOL isDir;
  NSFileManager *filemanager = [NSFileManager defaultManager];

  //Search dict into Slideshow user Library path
  paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES);
  userLibPath = [paths objectAtIndex: 0];
  _userPath = [[NSString alloc] initWithString: [userLibPath stringByAppendingPathComponent: USERSLIDESHOWSHORTCUTS]];
  
  //OK load it 
  if ( ( [filemanager fileExistsAtPath:_userPath isDirectory:&isDir] ) || (! isDir ) ) 
    {
      _keyBindingDict = [[NSMutableDictionary alloc] initWithContentsOfFile: _userPath];
    }

  //if cannot load user defaults:
  //use app defaults keybindings ( DefaultSlideShowKeyBindings.dict)
  if ( ! _keyBindingDict) 
    {
      keybindingPath = [[NSBundle mainBundle] pathForResource:RESOURCEDEFAULTSSLIDEKEYBINDINGS
					      ofType:@"dict"];
      _keyBindingDict = [[NSMutableDictionary alloc] initWithContentsOfFile: keybindingPath];
    }
  

  //TESTING 
  if (! _keyBindingDict) 
    NSLog(@"WARNING WARNING no_keyBindingDict WARNING WARNING");

  {
    unsigned i,count;
    _actions = [[NSMutableArray alloc] init];
    NSArray *bindingsValues = [_keyBindingDict allValues];
    
    count = [bindingsValues count];

    for (i=0;i<count;i++)
      {
	if ( ! [_actions containsObject: [bindingsValues objectAtIndex:i]] ) 
	  [_actions addObject:[bindingsValues objectAtIndex:i]];
      }
    //[bindingsValues release];
  }
}
@end

/*********************************************/
/********** Shortcuts implementation ********/
/*********************************************/
@implementation Shortcuts

-(id) init
{
  if ( sharedShortcurts ) 
    [self dealloc];
  else
    {
      if (! ( self = [super init] ) )
	return nil;
      {
	[self _initShortcuts];
	sharedShortcurts = self;
      }
    }
  return sharedShortcurts;
}

-(void) dealloc
{
  if ( _keyBindingDict ) 
    [_keyBindingDict release];
  if ( _actions ) 
    [_actions release];
  if (_userPath)
    [_userPath release];
  
  [super dealloc];
}

+(id) sharedShortcuts
{
  if ( ! sharedShortcurts ) 
    return [[self alloc] init];
  else
    return sharedShortcurts;
}


-(NSArray *) actions
{
  return _actions;
}


-(void) setShortcut:(NSString*) shortcut
	  forAction: (NSString *) action
{
  NS_DURING
    {
      [_keyBindingDict setObject:action forKey:shortcut];
    }
  NS_HANDLER
    {
      printf("Should RAISE an exception or do something\n");
    }
  NS_ENDHANDLER
}

-(void) removeShortcut: (NSString*) shortcut
{
  [_keyBindingDict removeObjectForKey:shortcut];
}

-(SEL) actionForKey:(NSString*) key
{
  NSString *actionString; 
  if ( ( actionString =  [_keyBindingDict objectForKey: key] ) ) 
    return NSSelectorFromString(actionString);
  else
    return NULL;
}

-(NSArray *) shortcutsForAction: (NSString *) action
{
  NSMutableArray *array = [[NSMutableArray alloc] init];
  NSEnumerator *enumerator;
  id key;
  //TODO : IMP optim.
  enumerator = [_keyBindingDict keyEnumerator]; 

  if (! enumerator ) 
    return nil;

  while ( (key = [enumerator nextObject]) ) 
    {
      if ( [[_keyBindingDict objectForKey: key] isEqualToString: action] ) 
	{
	  [array addObject: key];
	}
    }
  //TODO ?? 
  return array;
}

-(void) synchronize
{
  if ( [_keyBindingDict writeToFile:_userPath atomically:YES] ) 
    {
      NSLog(@"Synchronize OK");
      //Send a Notification : "shortcuts have changed"
      [[NSNotificationCenter defaultCenter] postNotificationName:SLIDESHOWSHORTCUTSNOTIFICATION
					    object:nil];
    }
}
@end
