/****************************************************************************
 *   Copyright (C) 2004 by Arboretum Systems, Inc.                          *
 *   Technical administrator: Alain Mazy, hav@mazy.be                       *
 *   Lead program designer: Georges Jaroslaw, gjaro@arboretum.com           *
 *                                                                          *
 *   HyperEngine-AV is a video, audio and text editor that can be used to   *
 *   record, import, edit, process and arrange together video, sound and    *
 *   text. These are all achieved in the program's free-form document       *
 *   window, with no limitations to the number of tracks.                   *
 *   The purpose of this program is to provide to users at all levels of    *
 *   expertise a readily accessible tool enabling them to create movies,    *
 *   slide shows or presentations.                                          *
 *                                                                          *
 *   HyperEngine-AV itself is free software. However, plug-ins that can be  *
 *   used as add-ons to HyperEngine-AV may or may not be free software, at  *
 *   the discretion of each plug-in developer and as specified by these     *
 *   plug-ins' respective licenses.                                         *
 *   You can redistribute HyperEngine-AV itself 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.                                             *
 *                                                                          *
 *   HyperEngine-AV 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 all applicable 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.              *
 ****************************************************************************/

#import "MIDocumentController.h"
#import "MIApplication.h"
#import "MenuTags.h"
#import "MIStartingPoint.h"

#ifndef ZzVerbose_h
#include "ZzVerbose.h"
#endif //ZzVerbose_h

#ifdef MTG_USE_LICENSER_KIT

#ifdef MTG_FULL_VERSION
#ifndef L_TEST
#define L_TEST 1
#endif
#endif

#ifdef L_TEST
#import "CSOneWay.h"
#import "MainApp.h"
#endif

#endif //#ifdef MTG_USE_LICENSER_KIT


static inline unsigned int unverifyChallenge(unsigned int t)
{
	t    = (t >> 13) | ((((t >> 1) ^ (t)) & 0x3FFF) <<  1);
	t    = (t >> 14) | ((((t >> 1) ^ (t)) & 0x3FEF) <<  1);
	t    = (t >>  1) | ((((t >> 1) ^ (t)) & 0x1001) << 13);
	t    = (t >> 13) | ((((t >> 1) ^ (t)) & 0x3FFF) <<  1);
	t    = (t >> 14) | ((((t >> 1) ^ (t)) & 0x7FFF) <<  1);

	return t;
}

NSString *MTGDocumentAddedNotification = @"MTG Document Added Notification";
NSString *MTGDocumentRemovedNotification = @"MTG Document Removed Notification";
NSString *MTGCurrentDocumentChangedNotification = @"MTG Current Document Changed Notification";
NSString *MTGCurrentDocumentKey = @"MTG Current Document key";
NSString *MTGAddedDocumentKey = @"MTG Added Document key";

#undef VER_DEF_TOPIC
#define VER_DEF_TOPIC MIDocumentController

@implementation MIDocumentController

+ (MIDocumentController*)sharedDocumentController {
    static MIDocumentController* sdc = nil;

    if ( sdc == nil ) 
	{
		sdc = [[self alloc] init];
    }
    return sdc;
}

- (MIDocumentController*)init 
{
    if (( self = [super init] )) 
	{
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeMain:) name:NSWindowDidBecomeMainNotification object:nil];
    }
    return self;
}

- (void)windowDidBecomeMain:(NSNotification *)notification
{
	//vernl(6,"[MIDocumentController windowDidBecomeMain]");
	NSDocument* document = [[[notification object] windowController] document];
	NSDictionary *dict = nil ;
		
	if ( document )
	{
		if ( fCurrentDocument != document )
		{
			fCurrentDocument = document;
			if ( fCurrentDocument )
			{
				dict = [NSDictionary dictionaryWithObject:fCurrentDocument forKey:MTGCurrentDocumentKey];
			}
			[[NSNotificationCenter defaultCenter] postNotificationName:MTGCurrentDocumentChangedNotification object:self userInfo:dict];
		}
	}
}

- (void)dealloc 
{
	vernl(6,"[MIDocumentController dealloc]");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeMainNotification object:nil];
    [super dealloc];
}

- (void)addDocument:(NSDocument*)document 
{
	vernl(6,"[MIDocumentController addDocument]");
	NSDictionary *dict = nil ;
    [super addDocument:document];
	dict = [NSDictionary dictionaryWithObject:document forKey:MTGAddedDocumentKey];
    [[NSNotificationCenter defaultCenter] postNotificationName:MTGDocumentAddedNotification object:self userInfo:dict];
}

- (void)removeDocument:(NSDocument*)document 
{
	vernl(6,"[MIDocumentController removeDocument] event time stamp = %f" << [[NSApp currentEvent] timestamp]);

	fCurrentDocument = nil; // $$$MONODOC
	[NSApp resetMainViewController]; // $$$MONODOC

	[[NSNotificationCenter defaultCenter] postNotificationName:MTGDocumentRemovedNotification object:self userInfo:nil];
	
	[super removeDocument:document];
	
	if([[self documents] count] == 0)
	{
		vernl(6,"[MIDocumentController removeDocument] : last doc has been dealloced...");
	}
}

- (NSDocument*)currentDocument {
#ifdef L_TEST
	if ( ((float)random())/((float)LONG_MAX) > .999 ) {
		unsigned int challenge = createTimeChallenge();
	
		if (verifyChallenge ((int)[NSApp searchForMenuitemWithTag:challenge]) != challenge) {
			challenge = [NSApp isHostFeatureExtraModeWithChallenge:unverifyChallenge((unsigned int)self)];
			if ( challenge ) {
				challenge = nil;
			} else challenge = createTimeChallenge();
		}
	}
#endif
	
	return fCurrentDocument;
}

- (BOOL)validateMenuItem:(NSMenuItem *)anItem {
	SEL action = [anItem action];
	
	if ( action == NSSelectorFromString(@"openDocument:") ) {
		if ( [[self documents] count] == 0 ) return YES;
		else return NO;
	}
		
	return [super validateMenuItem:anItem];
}

- (id)openDocumentWithContentsOfURL:(NSURL *)aURL display:(BOOL)flag {
	if ( [[self documents] count] == 0 ) {
		[self noteNewRecentDocumentURL:aURL];
		return [super openDocumentWithContentsOfURL:aURL display:flag];
	}
	else {
		NSRunAlertPanel(@"Couldn't open document", @"HyperEngine-AV can open up to one document simultaneously. You should close the \"%@\" document before opening another one.", @"OK", nil, nil, [fCurrentDocument displayName]);
		return nil;
	}
}

- (id)openDocumentWithContentsOfFile:(NSString *)fileName display:(BOOL)flag {
	if ( [[self documents] count] == 0 ) {
		NSURL *url = [NSURL fileURLWithPath:fileName];
		[self noteNewRecentDocumentURL:url];
		return [super openDocumentWithContentsOfFile:fileName display:flag];
	}
	else {
		NSRunAlertPanel(@"Couldn't open document", @"HyperEngine-AV can open up to one document simultaneously. You should close the \"%@\" document before opening another one.", @"OK", nil, nil, [fCurrentDocument displayName]);
		return nil;
	}
}

- (IBAction)clearRecentDocuments:(id)sender {
	[super clearRecentDocuments:sender];
	[[MIStartingPoint startingPoint] updatePopupButton];
}

- (void)updateRecentDocuments {
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSMutableArray *array = [NSMutableArray array];
	NSEnumerator *enumerator = [[self recentDocumentURLs] objectEnumerator];
	NSURL *url;

	while (( url = [enumerator nextObject] )) {
		if ( [fileManager fileExistsAtPath:[url path]] ) {
			[array addObject:url];
		}
	}

	if ( [[self recentDocumentURLs] count] != [array count] ) {
		enumerator = [array objectEnumerator];
		[super clearRecentDocuments:nil];

		while (( url = [enumerator nextObject] )) {
			[self noteNewRecentDocumentURL:url];
		}
	}
}


@end
