/*
    MakeBuilder.h

    Interface declaration of the MakeBuilder class for the ProjectManager
    application.

    Copyright (C) 2005  Saso Kiselkov

    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#import <Foundation/NSObject.h>
#import "../../ProjectModule.h"

@class NSString,
       NSMutableArray,
       NSFileHandle,
       NSNotification;

@class NSView,
       NSTableView,
       NSTableColumn,
       NSTask;

@protocol MakeBuilderDelegate;

/**
 * Notification posted when the builder starts building the project.
 * The user info dictionary contains the following keys:
 * {
 *   Project = (ProjectDocument *) builderProject;
 *   Target = "<build-target>";
 * }
 */
#define MakeBuilderBuildDidBeginNotification \
  @"MakeBuilderBuildDidBeginNotification"

/**
 * Notification posted when a project build has ended. The user info
 * dictionary contains the following keys:
 * {
 *   Project = (ProjectDocument *) builderProject;
 *   Target = "<build-target>";
 *   Success = (NSNumber * BOOL) buildSucceeded;
 * }
 */
#define MakeBuilderBuildDidEndNotification \
  @"MakeBuilderBuildDidEndNotification"

/**
 * Notification posted when the builder starts cleaning the project.
 * The user info dictionary contains the following keys:
 * {
 *   Project = (ProjectDocument *) builderProject;
 *   Target = "<clean-target>";
 * }
 */
#define MakeBuilderCleanDidBeginNotification \
  @"MakeBuilderCleanDidBeginNotification"

/**
 * Notification posted when a project clean has ended. The user info
 * dictionary contains the following keys:
 * {
 *   Project = (ProjectDocument *) builderProject;
 *   Target = "<clean-target>";
 *   Success = (NSNumber * BOOL) cleanSucceeded;
 * }
 */
#define MakeBuilderCleanDidEndNotification \
  @"MakeBuilderCleanDidEndNotification"

typedef enum {
  MakeBuilderReady,
  MakeBuilderBuilding,
  MakeBuilderCleaning
} MakeBuilderState;

@interface MakeBuilder : NSObject <ProjectModule>
{
  // weak reference
  ProjectDocument * document;

  NSDictionary * info;

  id bogusWindow, view;

  id buildOutput;
  id buildArgs;
  id buildArgsManipulationMatrix;
  id buildArgsMovementMatrix;
  id buildErrors;
  id buildTarget;
  id verboseBuild;
  id warnings;
  id allWarnings;

  NSArray * targets;
  NSMutableArray * buildArguments;
  NSMutableArray * buildErrorList;
  NSString * lastIncompleteOutputLine;
  NSString * lastIncompleteErrorLine;

  // This stack holds the directories as the build processes passes through
  // subprojects. When a line of format "make[*Entering directory `*" is
  // received, the new build directory is put on top of this stack, and once
  // a "make[*Leaving directory`*" line received, the top element is popped
  // off. This way the builder can correctly follow the building process
  // when we have subprojects (which reside in subdirectories).
  NSMutableArray * buildDirectoryStack;

  MakeBuilderState state;

  NSTask * task;
  NSFileHandle * outputFileHandle, * errorFileHandle;

  id <MakeBuilderDelegate> delegate;    // weak reference
}

- (void) build: sender;
- (void) buildTarget: (NSString *) target;

- (void) clean: sender;
- (void) cleanTarget: (NSString *) target;

- (void) stopOperation: sender;

- (BOOL) isBusy;

- (void) addBuildArgument: (id)sender;
- (void) removeBuildArgument: (id)sender;
- (void) moveBuildArgumentUp: sender;
- (void) moveBuildArgumentDown: sender;

- (void) openErrorFile: sender;

- (int) numberOfRowsInTableView: (NSTableView *)aTableView;
- (id) tableView: (NSTableView *)aTableView 
objectValueForTableColumn: (NSTableColumn *)aTableColumn 
             row: (int)rowIndex;
- (void) tableView: (NSTableView *)aTableView 
    setObjectValue: (id)anObject 
    forTableColumn: (NSTableColumn *)aTableColumn
               row: (int)rowIndex;

- (void) collectOutput: (NSNotification *) notif;
- (void) collectErrorOutput: (NSNotification *) notif;

- (void) buildCompleted: (NSNotification *) notif;
- (void) cleanCompleted: (NSNotification *) notif;

- (void) buildOptionChanged: sender;

@end
