/*
**  CriterionView.h
**
**  Copyright (c) 2004
**
**  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
*/

#ifndef __CriterionView__
#define __CriterionView__

#include "AppKit/AppKit.h"
//#include "GNUstep.h"
#include "Utilities.h"

/* Criterion is in the form of /type/subject/verb/object/ 
 * type specify the type of object and change verb.
 * subject is NSString.
 * object can be NSString, NSNumber, NSDate, NSArray(more than one object)
 * depending on the type.
 * CriterionAllType suggest the type can be anything.
 * Try tp parse object to know its type.
 */

typedef enum _CriterionType {
  CriterionAnyStringType = 0,
  CriterionStringType = 1,
  CriterionDateType = 2,
  CriterionNumberType = 3,
  CriterionSelectionType = 4, /* Fall back to String is selections is not set */
  CriterionContentType, /* Content search */
  CriterionTypeCount
} CriterionType;

typedef enum _CriterionVerb {
  CriterionContainsVerb = 1, /* string */
  CriterionDoesNotContainVerb = 2, /* string */
  CriterionIsVerb = 3, /* string, date, number, selection */
  CriterionIsNotVerb = 4, /* string, date, number, selection */
  CriterionStartsWithVerb = 5, /* string */
  CriterionEndsWithVerb = 6, /* string */
  CriterionMatchRegularExpressionVerb = 7, /* string */
  CriterionIsAfterVerb = 9, /* date */
  CriterionIsBeforeVerb = 10, /* date */
  CriterionIsInTheLastVerb = 11, /* date */
  CriterionIsNotInTheLastVerb = 12, /* date */
  CriterionIsInTheRangeVerb = 13, /* date, number */
  CriterionIsGreaterThanVerb = 14, /* number */
  CriterionIsLessThanVerb = 15, /* number */
  CriterionVerbCount
} CriterionVerb;

typedef enum _CriterionDateUnit {
  CriterionErrorUnit = 0,
  CriterionSecondUnit = 1,
  CriterionMinuteUnit = 60,
  CriterionHourUnit = 3600,
  CriterionDayUnit = 86400,
  CriterionWeekUnit = 604800,
  CriterionMonthUnit = 2592000,
  CriterionYearUnit = 31536000
} CriterionDateUnit;

static NSString *SubjectColumnIdentifier = @"SubjectColumnIdentifier";
static NSString *VerbColumnIdentifier = @"VerbColumnIdentifier";
static NSString *ObjectColumnIdentifier = @"ObjectColumnIdentifier";

@interface CriterionView : NSControl
{
  NSMutableArray *subjectCellArray;
  NSMutableArray *verbCellArray;
  NSMutableArray *objectViewArray;

  float cell_height;
  BOOL isBordered;
  BOOL isSmallControlSize;
  unsigned int maxCriterions;

  id dataSource;
  id delegate;

  NSArray *verbsForAnyString, *verbsForString, *verbsForDate, *verbsForNumber;
  NSArray *verbsForSelection, *verbsForContent;
  NSMutableArray *verbStringsForAnyString, *verbStringsForString;
  NSMutableArray *verbStringsForDate, *verbStringsForNumber;
  NSMutableArray *verbStringsForSelection;
  NSMutableArray *verbStringsForContent;

  /* Cache */
  NSMutableArray *allSubjects;

  RegExFloatNumber numberType;
  RegExDate dateType;
}

- (void) reloadSubjects;
- (void) reloadSelections;
- (void) reloadData;

- (void) setDataSource: (id) object;
- (id) dataSource;
- (void) setDelegate: (id) object;
- (id) delegate;
- (void) setFloatNumberRegExType: (RegExFloatNumber) type;
- (void) setDateRegExType: (RegExDate) type;

- (void) setBordered: (BOOL) flag;
- (BOOL) isBordered;
- (void) setSmallControlSize: (BOOL) flag;
- (BOOL) isSmallControlSize;
- (void) setMaxCriterions: (unsigned int) number;
- (unsigned int) maxCriterions;
- (float) optimalHeight;

@end

@interface NSObject (CriterionViewDataSource)

/* read criterion */
- (unsigned int) numberOfCriterionsInView: (CriterionView *) view;
- (NSArray *) availableSubjectsOfCriterionsInView: (CriterionView *) view;
- (NSString *) criterionView: (CriterionView *) view
               subjectAtIndex: (unsigned int) index;
- (CriterionType) criterionView: (CriterionView *) view
                  typeOfSubject: (NSString *) subject;
- (NSArray *) criterionView: (CriterionView *) view
              availableSelectionsForSubject: (NSString *) subject;
- (CriterionVerb) criterionView: (CriterionView *) view
                    verbAtIndex: (unsigned int) index;
- (id) criterionView: (CriterionView *) view
       objectAtIndex: (unsigned int) index;

/* Set criterion */
- (void) addCriterionWithSubject: (NSString *) subject
                            verb: (CriterionVerb) verb
                          object: (id) object;
- (void) insertCriterionWithSubject: (NSString *) subject
                               verb: (CriterionVerb) verb
		  	     object: (id) object
			    atIndex: (unsigned int) index;
- (void) removeCriterionAtIndex: (unsigned int) index;
- (void) setCriterionWithSubject: (NSString *) subject
                            verb: (CriterionVerb) verb
                          object: (id) object
                         atIndex: (unsigned int) index;
@end

@interface NSObject (CriterionViewDelegate)
/* Called after add or remove criterion */
- (void) criterionDidChangeInView: (CriterionView *) view;
- (void) criterionViewProposeResizing: (CriterionView *) view
                               toSize: (NSSize ) proposedSize;
@end
#endif /* __CriterionView__ */
