1//
2//  PXAboutController.m
3//  Pixen-XCode
4//
5//  Created by Andy Matuschak on Sun Aug 01 2004.
6//  Copyright (c) 2004 Open Sword Group. All rights reserved.
7//
8
9#import "PXAboutController.h"
10#import "PXAboutPanel.h"
11
12#import <Foundation/NSArray.h>
13#import <Foundation/NSBundle.h>
14#import <Foundation/NSData.h>
15#import <Foundation/NSDictionary.h>
16#import <Foundation/NSNotification.h>
17#import <Foundation/NSTimer.h>
18#import <Foundation/NSValue.h>
19
20#import <AppKit/NSApplication.h>
21#import <AppKit/NSTextStorage.h>
22#import <AppKit/NSTextView.h>
23
24static PXAboutController *singleInstance = nil;
25
26@implementation PXAboutController
27
28-(id) init
29{
30	if ( singleInstance )
31    {
32		[self dealloc];
33		return singleInstance;
34    }
35
36
37	if ( ! ( self = [super init] ) )
38		return nil;
39
40	if ( ! [NSBundle loadNibNamed :@"PXAbout" owner:self] )
41	  NSLog(@"Warm the user");
42
43	singleInstance = self;
44
45	return singleInstance;
46}
47
48+(id) sharedAboutController
49{
50	if ( ! singleInstance  )
51		singleInstance = [[self alloc] init];
52
53	return singleInstance;
54}
55
56
57- (void)loadCreditsText
58{
59  id linkString = [NSString stringWithFormat:@"<a href=\"http://www.opensword.org/license.php\">MIT License</a>"];
60
61  id plainString = [[[NSMutableString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Credits" ofType:@"html"]] autorelease];
62
63  [plainString replaceOccurrencesOfString:@"<PXLICENSE>"
64	       withString:linkString
65	       options:nil
66	       range:NSMakeRange(0,[(NSString *)plainString length])];
67
68
69#ifdef __COCOA__
70  NSData *htmlData = [NSData dataWithBytes:[plainString cString] length:[(NSString *)plainString length]];
71  NSDictionary *attributedOptions = [NSDictionary dictionaryWithObject:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]] forKey:@"BaseURL"];
72  NSAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithHTML:htmlData options:attributedOptions documentAttributes:nil] autorelease];
73  [[credits textStorage] setAttributedString:attributedString];
74#else
75  [credits setString :plainString];
76#endif
77}
78
79
80
81- (void)createPanel
82{
83	id content;
84	aboutPanel = [[PXAboutPanel alloc]
85		 initWithContentRect:[[panelInNib contentView] frame]
86				   styleMask:NSBorderlessWindowMask
87					 backing:[panelInNib backingType]
88					   defer:NO];
89
90	[aboutPanel setBackgroundColor: [NSColor whiteColor]];
91	[aboutPanel setHasShadow: YES];
92	[aboutPanel setNextResponder: self];
93	[aboutPanel setBecomesKeyOnlyIfNeeded: NO];
94	[aboutPanel setDelegate: self];
95	[aboutPanel setLevel:NSModalPanelWindowLevel];
96
97
98	content = [[panelInNib contentView] retain];
99	[content removeFromSuperview];
100	[(PXAboutPanel *)aboutPanel setContentView:content];
101	[content release];
102}
103
104//	Watch for notifications that the application is no longer active, or that
105//	another window has replaced the About panel as the main window, and hide
106//	on either of these notifications.
107- (void) watchForNotificationsWhichShouldHidePanel
108{
109	//	This works better than just making the panel hide when the app
110	//	deactivates (setHidesOnDeactivate:YES), because if we use that
111	//	then the panel will return when the app reactivates.
112	[[NSNotificationCenter defaultCenter] addObserver: self
113											 selector: @selector(hidePanel)
114												 name: NSApplicationDidResignActiveNotification
115											   object: nil];
116
117	//	If the panel is no longer main, hide it.
118	//	(We could also use the delegate notification for this.)
119	[[NSNotificationCenter defaultCenter] addObserver: self
120											 selector: @selector(hidePanel)
121												 name: NSWindowDidResignMainNotification
122											   object: aboutPanel];
123
124	[[NSNotificationCenter defaultCenter] addObserver: self
125											 selector: @selector(hidePanel)
126												 name: NSWindowDidResignKeyNotification
127											   object: aboutPanel];
128}
129
130- (void)dealloc
131{
132	[aboutPanel release];
133	[[NSNotificationCenter defaultCenter] removeObserver:self];
134	[super dealloc];
135}
136
137- (void)setupPanel
138{
139	[self createPanel];
140	[self loadCreditsText];
141	[aboutPanel center];
142	[self watchForNotificationsWhichShouldHidePanel];
143}
144
145- (void)showPanel:(id) sender
146{
147	if (!aboutPanel)
148    {
149		[self setupPanel];
150    }
151	[aboutPanel setAlphaValue:0.0];
152	[aboutPanel makeKeyAndOrderFront:nil];
153	[fadeTimer invalidate];
154	[fadeTimer release];
155	fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.05
156												  target:self
157												selector:@selector(fade:)
158												userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:0.0], @"opacity",
159													[NSNumber numberWithFloat:.1], @"direction",
160													nil] repeats:NO] retain];
161}
162
163
164- (void)hidePanel
165{
166	[fadeTimer invalidate];
167	[fadeTimer release];
168
169	fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.05
170												  target:self
171												selector:@selector(fade:)
172												userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:1.0], @"opacity",
173													[NSNumber numberWithFloat:-.1],@"direction",
174													nil] repeats:NO] retain];
175	//[aboutPanel orderOut:nil];
176}
177
178
179- (void)fade:(NSTimer *)timer
180{
181	float alphaValue = [[[timer userInfo] objectForKey:@"opacity"] floatValue];
182	float fadeDirection = [[[timer userInfo] objectForKey:@"direction"] floatValue];
183	[aboutPanel setAlphaValue:alphaValue];
184	[fadeTimer invalidate];
185	[fadeTimer release];
186
187	if ( ( (alphaValue > 0 ) &&  ( fadeDirection < 0 ) )
188		 || ( (alphaValue < 1)  && (fadeDirection > 0 ) ) )
189    {
190		fadeTimer = [[NSTimer scheduledTimerWithTimeInterval:.02
191													  target:self
192													selector:@selector(fade:)
193													userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
194														[NSNumber numberWithFloat:alphaValue+fadeDirection], @"opacity",
195														[NSNumber numberWithFloat:fadeDirection], @"direction",
196														nil] repeats:NO] retain];
197    }
198	else
199    {
200		fadeTimer = nil;
201		//[aboutPanel setAlphaValue:1.0 - alphaValue];
202		if (alphaValue <= 0) {
203			[aboutPanel orderOut:nil];
204		}
205    }
206}
207
208- (void)mouseDown:(NSEvent *) event
209{
210	[self hidePanel];
211}
212
213@end
214