//
// EditorController.j
// Editor
//
// Created by Francisco Tolmasky on Date.
// Copyright 2005 - 2008, 280 North, Inc. All rights reserved.
//

BASE_URL = @"Server/"; // DEPLOYMENT

import <AppKit/CPToolbar.j>
import <AppKit/CALayer.j>
import <AppKit/CGGeometry.j>
import <AppKit/CPColorPanel.j>

import <SlideKit/SKSlide.j>
import <SlideKit/SKPresentationView.j>

import "BugReporter.j"
import "FormatBar.j"
import "MediaWindowController.j"
import "PresentationController.j"
import "SharePanel.j"
import "SlideDetail.j"
import "SlideEditor.j"
import "SlideLayoutPanel.j"
import "SlideNavigator.j"
import "ThemePanel.j"
import "Themes.j"


var SIDEBAR_WIDTH       = 200.0,
    FORMAT_BAR_HEIGHT   = 26.0;

@implementation EditorController : CPWindowController
{
    PresentationController  _presentationController;
    
    SlideNavigator          _slideNavigator;
    SlideDetail             _slideDetail;
    SlideEditor             _slideEditor;
    
    FormatBar               _formatBar;
    Toolbar                 _toolbar;
}

+ (void)initialize
{
    if (self != [EditorController class])
        return;
        
    [self initializeToolbar];
}

- (void)windowDidLoad
{
    var theWindow = [self window],
        toolbar = [[CPToolbar alloc] initWithIdentifier:@"EditingToolbar"];

    [toolbar setDelegate:self];
    [theWindow setToolbar:toolbar];

    var contentView = [[self window] contentView],
        bounds = [contentView bounds];
    
    // Format Bar
    _formatBar = [[FormatBar alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), FORMAT_BAR_HEIGHT)];
    
    [_formatBar setAutoresizingMask:CPViewWidthSizable];

    [contentView addSubview:_formatBar];

    // Set up our slide detail view.
    var slideDetailHeight = [SlideDetail slideDetailHeightForState:SlideDetailUndocked];
    
    _slideDetail = [[SlideDetail alloc] initWithFrame:CGRectMake(0.0, CGRectGetHeight(bounds) - slideDetailHeight, SIDEBAR_WIDTH, slideDetailHeight)];
    
    [_slideDetail setAutoresizingMask:CPViewMinYMargin];
    [_slideDetail setPresentationController:_presentationController];

	[_slideDetail setDelegate: self];
    
    [contentView addSubview:_slideDetail];

    // Set up our slide navigator.
    scrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(0.0, FORMAT_BAR_HEIGHT, 200.0, CPRectGetHeight(bounds) - (FORMAT_BAR_HEIGHT + slideDetailHeight))];
    
    _slideNavigator = [[SlideNavigator alloc] initWithFrame:CPRectMake(0.0, FORMAT_BAR_HEIGHT, 100.0, CPRectGetHeight(bounds) - (FORMAT_BAR_HEIGHT + slideDetailHeight))];
    [_slideNavigator setPresentationController:_presentationController];
   
    [scrollView setHasHorizontalScroller:NO];
    [scrollView setAutoresizingMask:CPViewMaxXMargin | CPViewHeightSizable];
   
    [scrollView setDocumentView:_slideNavigator];
    
    [contentView addSubview:scrollView];

    // Set up the Slide Editor.
    var navigatorWidth = CPRectGetWidth([scrollView frame]),
        scrollView = [[SlideEditorScrollView alloc] initWithFrame:CPRectMake(navigatorWidth, FORMAT_BAR_HEIGHT, CPRectGetWidth(bounds) - navigatorWidth, CPRectGetHeight(bounds) - FORMAT_BAR_HEIGHT)];

    _slideEditor = [[SlideEditor alloc] initWithFrame:CGRectMakeCopy([scrollView bounds])];

    [_slideEditor setPresentationController:_presentationController];
    [_slideEditor setDelegate:self];
    
    [scrollView setAutohidesScrollers:YES];
    [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];

    [scrollView setDocumentView:_slideEditor];
    
    [contentView addSubview:scrollView];
  
//    [self updateFormatBar];
  
//    [self setScale:1.0];
    [self setScale:-1.0];
//    [self setScale:2.0];

    [theWindow makeFirstResponder:_slideEditor];
    
    [super windowDidLoad];

    //FIXME: Ross - we should put onunload handlers somewhere better than this.  But this will do for now.
    window.onbeforeunload = function()
    {
        if ([[self document] isDocumentEdited])
            return "If you leave, you will lose any unsaved changes to your document.";
    }
}

- (void)setDocument:(Document)aDocument
{
    if (!_presentationController)
        _presentationController = [[PresentationController alloc] init];

    [_presentationController setPresentation:[aDocument presentation]];
    [_presentationController setUndoManager:[aDocument undoManager]];
    
    [super setDocument:aDocument];

    // So in theory, this is done in the nib, also, even if that were the case, since we switch up documents
    // it would break upon opening the second document.
    // NOTE: This is also when the window is first loaded -(CPWindow)window -> windowDidLoad
    [[self window] setDelegate:aDocument];
}

- (void)setScale:(float)aScale
{
    if (aScale == -1.0)
    {
        if ([_slideEditor scalesContentToFit])
            return;
        
        [_slideEditor setScalesContentToFit:YES];
        [_slideEditor setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
    }
    else
    {
        if ([_slideEditor scale] == aScale)
            return;
        
        [_slideEditor setScale:aScale];
    }
}

@end

@implementation EditorController (blah)

- (void)addShape:(id)aSender
{
    var slide = [_presentationController selectedSlide],
        slideSize = [slide size],
        shape = [aSender selectedShape];
    
    [shape setPosition:CGPointMake(slideSize.width / 2.0, slideSize.height / 2.0)];
        
    [slide beginEditing];
    [slide addShape:shape];
    [slide endEditing];
}

// FIXME: This should really be in some sort of app controller of some sort.
- (void)feedback:(id)sender
{
    var feedbackPanel = [BugReporter sharedBugReporter];
    
    [feedbackPanel center];
    [feedbackPanel makeKeyAndOrderFront:self];
}

- (void)showPresentation:(id)aSender
{
    var presentationView = [[SKPresentationView alloc] initWithFrame:CGRectMakeZero()];
    
    [presentationView setPresentation:[_presentationController presentation]];

    [presentationView startPresentationAtIndex:[_presentationController selectionIndex] enterFullScreen:YES];

    if(window.controller)
        window.controller.goFullScreen_(self);
}

- (void)showMedia:(id)aSender
{
    [[MediaWindowController sharedMediaWindowController] showWindow:self];
}

- (void)showMovies:(id)sender
{
    [[MediaWindowController sharedMediaWindowController] showWindow:self];
	[[MediaWindowController sharedMediaWindowController] selectMovies];
}

- (void)showPictures:(id)sender
{
    [[MediaWindowController sharedMediaWindowController] showWindow:self];
	[[MediaWindowController sharedMediaWindowController] selectPictures];
}

- (void)showShapes:(id)sender
{
    [[MediaWindowController sharedMediaWindowController] showWindow:self];
	[[MediaWindowController sharedMediaWindowController] selectShapes];
}

- (void)showInspector:(id)aSender
{
    [[InspectorWindowController sharedInspectorWindowController] showWindow:self];
}

- (void)front:(id)aSender
{
    var selectedGraphicViews = [[_slideEditor selectedGraphicViews] copy];
    
    [_slideEditor unselectAllGraphicViews];

    [selectedGraphicViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    [[_slideEditor graphicViews] removeObjectsInArray:selectedGraphicViews];
    
    var i = 0,
        count = [selectedGraphicViews count];
    
    for (; i < count; ++i)
        [_slideEditor addGraphicView:selectedGraphicViews[i]];
        
    [_slideEditor selectGraphicViews:selectedGraphicViews byExtendingSelection:NO];
}

- (void)back:(id)aSender
{
}

- (void)delete:(id)aSender
{
    [_slideEditor deleteBackward:self];
}

- (void)text:(id)aSender
{
    var text = [SKShape textShape],
        slide = [_presentationController selectedSlide],
        slideSize = [slide size],
        shapeSize = CGSizeMake(150.0, 100.0);
    
    [text setSize:shapeSize];
    [text setPosition:CGPointMake(slideSize.width / 2.0, slideSize.height / 2.0)];
    
    [slide beginEditing];
    [slide addShape:text];
    [slide endEditing];
}

- (void)newSlide:(id)aSender
{
    [_presentationController insertSlide:self];
}

- (void)duplicateSlide:(id)aSender
{
    [_slideNavigator copy:self];
    [_slideNavigator paste:self];
}

- (void)deleteSlide:(id)aSender
{
    [_presentationController removeSlides:self];
}

- (void)login:(id)sender
{
    [[LoginPanel sharedLoginPanel] beginWithModalDelegate:nil didEndSelector:nil contextInfo:nil];
}

- (void)logout:(id)sender
{
    [[LoginController sharedLoginController] logout: self];
}

- (void)download:(id)aSender
{
    [[self document] FIXME_download];
}

- (void)share:(id)sender
{
    [[SharePanel sharedSharePanel] showPanelForDocument: [self document]];
}

- (void)changeTheme:(id)aSender
{
    var slide = [_presentationController selectedSlide];
    
    [[ThemePanel sharedThemePanel] beginWithInitialSelectedSlideMaster:[slide slideMaster] modalDelegate:self didEndSelector:@selector(themePanel:didEndWithReturnCode:create:) contextInfo:NO];
}

- (void)themePanel:(ThemePanel)aThemePanel didEndWithReturnCode:(int)aReturnCode create:(BOOL)shouldCreate
{
    if (aReturnCode == CPCancelButton)
        return;
    
    [[_presentationController presentation] setSlideMaster:[aThemePanel selectedSlideMaster] forSlidesWithSlideMaster:[[_presentationController selectedSlide] slideMaster]];
}

- (void)changeSlideLayout:(id)aSender
{
    var slide = [_presentationController selectedSlide];

    [[SlideLayoutPanel sharedSlideLayoutPanel] beginForSlideMasters:[[slide slideMaster]] initialSelectedSlideLayout:[slide slideLayout] modalDelegate:self didEndSelector:@selector(slideLayoutPanel:didEndWithReturnCode:)];
}

- (void)slideLayoutPanel:(SlideLayoutPanel)aSlideLayoutPanel didEndWithReturnCode:(int)aReturnCode
{
    if (aReturnCode == CPCancelButton)
        return;
    
    var slide = [_presentationController selectedSlide];
    
    [slide beginEditing];
    [slide setSlideLayout:[aSlideLayoutPanel selectedSlideLayout]];
    [slide endEditing];
}

- (void)slideDetail:(SlideDetail)sender didChangeState:(int)state
{
	var detailFrame = [_slideDetail frame],
		scrollView = [_slideNavigator enclosingScrollView],
		navigatorFrame = [scrollView frame];
		
	var	newY = CGRectGetHeight([[[self window] contentView] bounds]) - [SlideDetail slideDetailHeightForState:state],
		diff = detailFrame.origin.y - newY;
		
	[_slideDetail setFrameOrigin: CGPointMake(detailFrame.origin.x, newY)];
	[scrollView setFrameSize: CGSizeMake(navigatorFrame.size.width, navigatorFrame.size.height - diff)];
	
	//FIXME: This is a little hacky
	[_slideNavigator scrollToSelection]; 
}

@end

@implementation SKShape (EditorControllerAdditions)

+ (SKShape)textShape
{
    var textShape = [[[self class] alloc] init];
    
    [textShape setTextBody:@"Text"];
    [textShape setGeometryName:SKRectangleGeometryName];
    
    return textShape;
}

@end

@implementation EditorController (SlideEditorDelegate)

- (void)updateFormatBar
{
    // FIXME: We shouldn't iterate through the layers, but oh well.
    var layers = [_slideEditor selectedShapeLayers],
        count = layers.length;
    
    [_formatBar setEnabled:count > 0];

    if (!count)
        return;
    
    var textAttributes = nil;

    while (count--)
    {
        var layer = layers[count];
        
        if (!textAttributes)
        {
            var shape = [layer shape];
            
            // If it's a solid fill, reflect it, if not, just default to white.
            [_formatBar setFillColor:[[shape fillColor] colorForSlideMaster:[shape slideMaster]]];
            [_formatBar setOpacity:[shape opacity]];

            textAttributes = [layer selectedTextAttributes];
        }
        
        if (![layer allowsTextEditing])
        {
            textAttributes = nil;
            
            break;
        }
        else
            textAttributes = TextAttributesCombine(textAttributes, [layers[count] selectedTextAttributes]);
    }
    
    [_formatBar setTextAttributes:textAttributes];
}

- (void)slideEditorDidChangeSelection:(SlideEditor)aSlideEditor
{
    [self updateFormatBar];
}

- (void)slideEditorDidChangeTextSelection:(SlideEditor)aSlideEditor
{
    [self updateFormatBar];
}

- (void)slideEditorDidChangeTextAttributes:(SlidEditor)aSlideEditor
{
    [self updateFormatBar];
}

@end

import "EditorControllerToolbar.j"
