/*
**  FontAttributesManager.m
**
**  Copyright (c) 2003
**
**  Author: Yen-Ju Chen <yjchenx@hotmail.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 "FontAttributesManager.h"
#include "Utilities.h"
#include <CodeEditorView/RulesetManager.h>
#include <AppKit/AppKit.h>

static FontAttributesManager *sharedManager;

@implementation FontAttributesManager

NSString *NSStringFromFont (NSFont *font)
{
  NSString *trait;
  NSFontTraitMask mask = [[NSFontManager sharedFontManager] traitsOfFont: font];
  NSNumber *size = [NSNumber numberWithFloat: [font pointSize]];

  if (mask & NSBoldFontMask)
    trait = @"Bold";
  else
    trait = @"Regular";

  if (mask & NSItalicFontMask)
    {
      if ([trait isEqualToString: @"Bold"])
        trait = [trait stringByAppendingString: @" Italic"];
      else
        trait = @"Italic";
    }

  return [NSString stringWithFormat: @"%@ %@ %d", 
                       [font displayName], trait, [size intValue]];
}

+ (FontAttributesManager *) sharedFontAttributesManager
{
  if (!sharedManager)
    {
      sharedManager = [[FontAttributesManager alloc] init];
    }
  return sharedManager;
}

- (NSPanel *) fontAttributesPanel;
{
  if (fontAttributesPanel == nil)
    {
      if(NO == [NSBundle loadNibNamed: @"FontAttributesPanel.gorm" owner: self])
        {
           NSBeep();
           return nil;
        }
    }
  return fontAttributesPanel;
}

/* Font Attributes Panel */
- (void) orderFrontFontAttributesPanel: (id) sender
{
  NSFont *font;
  int i;

  if ([self fontAttributesPanel] == nil)
    {
       NSBeep();
       return;
    }

  /* Set up attributes */
  rulesetManager = [RulesetManagerClass() sharedRulesetManager];

  /* Cache color */
  [colorCache setObject: [rulesetManager colorForType: @"Normal"]
                 forKey: @"Normal"];
  [colorCache setObject: [rulesetManager colorForType: @"Comments"]  
                 forKey: @"Comments"]; 
  [colorCache setObject: [rulesetManager colorForType: @"Strings"]  
                 forKey: @"Strings"]; 
  [colorCache setObject: [rulesetManager colorForType: @"Preprocessor"]  
                 forKey: @"Preprocessor"]; 
  [colorCache setObject: [rulesetManager colorForType: @"Keywords"]  
                 forKey: @"Keywords"]; 
  [colorCache setObject: [rulesetManager colorForType: @"KnownTypes"]  
                 forKey: @"KnownTypes"]; 

  /* Cache Font and Trait */
  font = [rulesetManager normalFont];
  [fontCache setObject: font forKey: @"Normal"];

  font = [rulesetManager fontForType: @"Comments"];
  [fontCache setObject: font forKey: @"Comments"];
  commentMask = [fontManager traitsOfFont: font];

  font = [rulesetManager fontForType: @"Strings"];
  [fontCache setObject: font forKey: @"Strings"];
  stringMask = [fontManager traitsOfFont: font];

  font = [rulesetManager fontForType: @"Preprocessor"];
  [fontCache setObject: font forKey: @"Preprocessor"];
  preprocessorMask = [fontManager traitsOfFont: font];

  font = [rulesetManager fontForType: @"Keywords"];
  [fontCache setObject: font forKey: @"Keywords"];
  keywordMask = [fontManager traitsOfFont: font];

  font = [rulesetManager fontForType: @"KnownTypes"];
  [fontCache setObject: font forKey: @"KnownTypes"];
  typeMask = [fontManager traitsOfFont: font];

  /* set up popup button */
  [commentTraitButton removeAllItems];
  [stringTraitButton removeAllItems];
  [preprocessorTraitButton removeAllItems];
  [keywordTraitButton removeAllItems];
  [typeTraitButton removeAllItems];
 
  for (i = 0; i < 4; i++)
    {
      NSString *trait;
      switch (i) {
        case 1:
          trait = @"Italic";
          break;
        case 2:
          trait = @"Bold";
          break;
        case 3:
          trait = @"Bold-Italic";
          break;
        default:
          trait = @"Regular";
      }
      
      [commentTraitButton addItemWithTitle: trait];
      [stringTraitButton addItemWithTitle: trait];
      [preprocessorTraitButton addItemWithTitle: trait];
      [keywordTraitButton addItemWithTitle: trait];
      [typeTraitButton addItemWithTitle: trait];
    }
 

  /* Get everything from defaults */
  [self revertToSavedFontAttributes: self];

  [fontAttributesPanel makeKeyAndOrderFront: self];
}

- (void) colorAction: (id) sender
{
  if (sender == normalColor)
    {
      [rulesetManager setColor: [sender color] forType: @"Normal"];
      return;
    }
  if (sender == commentColor)
    {
      [rulesetManager setColor: [sender color] forType: @"Comments"];
      return;
    }
  if (sender == stringColor)
    {
      [rulesetManager setColor: [sender color] forType: @"Strings"];
      return;
    }
  if (sender == preprocessorColor)
    {
      [rulesetManager setColor: [sender color] forType: @"Preprocessor"];
      return;
    }
  if (sender == keywordColor)
    {
      [rulesetManager setColor: [sender color] forType: @"Keywords"];
      return;
    }
  if (sender == typeColor)
    {
      [rulesetManager setColor: [sender color] forType: @"KnownTypes"];
      return;
    }
}

- (void) changeFont: (id) sender
{
  NSFont *font = [fontManager convertFont: [fontCache objectForKey: @"Normal"]];

  [rulesetManager setNormalFont: font];
  [normalFont setTitle: NSStringFromFont(font)];

  /* Change trait one by one */
  [self traitAction: commentTraitButton];
  [self traitAction: stringTraitButton];
  [self traitAction: preprocessorTraitButton];
  [self traitAction: keywordTraitButton];
  [self traitAction: typeTraitButton];
}

- (void) traitAction: (id) sender
{
  NSString *type = nil;
  int index;
  NSFontTraitMask trait;
  NSLog(@"traitAction %@", sender);
  if (sender == commentTraitButton)
    {
      type = @"Comments";
    }
  else if (sender == stringTraitButton)
    {
      type = @"Strings";
    }
  else if (sender == preprocessorTraitButton)
    {
      type = @"Preprocessor";
    }
  else if (sender == keywordTraitButton)
    {
      type = @"Keywords";
    }
  else if (sender == typeTraitButton)
    {
      type = @"KnownTypes";
    }

  index = [sender indexOfSelectedItem];
 
  switch (index) {
    case 1:
      trait = NSItalicFontMask;
      break;
    case 2:
      trait = NSBoldFontMask;
      break;
    case 3:
      trait = NSBoldFontMask|NSItalicFontMask;
      break;
    default:
      trait = 0;
  }   
  
  [rulesetManager setTrait: trait forType: type];
}

- (void) fontAction: (id) sender
{
  [fontManager orderFrontFontPanel: self];
  [fontAttributesPanel makeKeyAndOrderFront: self];

  [fontManager setSelectedFont: [fontCache objectForKey: @"Normal"] 
                    isMultiple: NO];
}

- (void) revertToSavedFontAttributes: (id) sender
{
  int i;

  /* set up color */
  [normalColor setColor: [colorCache objectForKey: @"Normal"]];
  [commentColor setColor: [colorCache objectForKey: @"Comments"]];
  [stringColor setColor: [colorCache objectForKey: @"Strings"]];
  [preprocessorColor setColor: [colorCache objectForKey: @"Preprocessor"]];
  [keywordColor setColor: [colorCache objectForKey: @"Keywords"]];
  [typeColor setColor: [colorCache objectForKey: @"KnownTypes"]];

  /* set up font */
  [normalFont setTitle: NSStringFromFont([fontCache objectForKey: @"Normal"])];
  [commentFont setTitle: NSStringFromFont([fontCache objectForKey: @"Comments"])];
  [stringFont setTitle: NSStringFromFont([fontCache objectForKey: @"Strings"])];
  [preprocessorFont setTitle: NSStringFromFont([fontCache objectForKey: @"Preprocessor"])];
  [keywordFont setTitle: NSStringFromFont([fontCache objectForKey: @"Keywords"])];
  [typeFont setTitle: NSStringFromFont([fontCache objectForKey: @"KnownTypes"])];
  
  for (i = 0; i < 5; i++)
    {
      NSFontTraitMask mask = 0;
      NSPopUpButton *button = nil;
      int index = 0;
      switch(i) {
        case 0:
          mask = commentMask;
          button = commentTraitButton;
          break;
        case 1:
          mask = stringMask;
          button = stringTraitButton;
          break;
        case 2:
          mask = preprocessorMask;
          button = preprocessorTraitButton;
          break;
        case 3:
          mask = keywordMask;
          button = keywordTraitButton;
          break;
        case 4:
          mask = typeMask;
          button = typeTraitButton;
          break;
      } 
      if (mask & NSItalicFontMask)
        index = 1;
      else if (mask & NSBoldFontMask)
        index = 2;
      else if (mask & (NSItalicFontMask | NSBoldFontMask))
        index = 3;
      else
        index = 0;
      [button selectItemAtIndex: index];
    }
}

- (void) windowWillClose: (NSNotification *) not
{
  if ([not object] == fontAttributesPanel)
    {
      [rulesetManager writeFontAttributesToUserDefaults];
      [[NSColorPanel sharedColorPanel] performClose: self];
      [[fontManager fontPanel: NO] performClose: self];
    }
}

- (id) init
{
  self = [super init];

  colorCache = [NSMutableDictionary new];
  fontCache = [NSMutableDictionary new];
  fontManager = [NSFontManager sharedFontManager];

  return self;
}

- (void) dealloc
{
  RELEASE(colorCache);
  RELEASE(fontCache);
  [super dealloc];
}

@end
