//
//  MWSummaryReport.m
//  TEST2
//
//  Created by matthew on Fri Oct 17 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

#import "MWSummaryReport.h"
#import "NSMutableNumber.h"
#import "tamsutils.h"
#import "tams.h"
#import "MWSortStackItem.h"
#define COLWIDTH 90
void MAKECOLUMN(NSTableView *TABLE,NSString *MYID, NSString *HEAD) {NSTableColumn *_t = [[NSTableColumn alloc] initWithIdentifier: MYID]; [_t setWidth: COLWIDTH];[TABLE addTableColumn: _t]; [[_t headerCell] setStringValue: HEAD];}


@implementation MWSummaryReport

-(id) init
{
    [super init];
    groupData = [[NSMutableArray alloc] init];
    summData = [[NSMutableArray alloc] init];
    summField = [[NSMutableString alloc] init];
    summSumField = [[NSMutableString alloc] init];
    dateFormat = [[NSMutableString alloc] init];
    tot = [[NSMutableNumber alloc] init];
    sortStack = [[NSMutableArray alloc] init];
    return self;
}

-(void) dealloc
{
    [groupData release];
    [summData release];
    [summField release];
    [summSumField release];
    [dateFormat release];
    [sortStack release];
    [tot release];
    [super dealloc];
}
-(BOOL) isEqualToLevel: (int) level first: (NSString *)c1 second: (NSString *) c2
{
    int ll;
    
    if(level == 0)
        return [c1 isEqualToString: c2];
    if([c1 isEqualToString: c2] ==YES) return YES;
    ll = compCodeByLevel(c1, c2);
    if(ll >= level) return YES;
    return NO;
}
-(IBAction) niceClose: (id) Sender
{
    [myWindow performClose: self];
}
-(void) sortData: (NSMutableArray *) who withStack: (NSArray *) stack
{
    NSMutableArray *ms = [[NSMutableArray alloc] init];
    FORALL(stack)
    {
        [ms addObject: temp];
        [who sortUsingFunction: stackComp context: ms];

    }
    ENDFORALL;
    [ms release];
}

-(void) setData: (NSMutableArray *) d andReport: (NSDictionary *) aReport;
{
    data = d;
    [groupData addObjectsFromArray: [aReport objectForKey: @"groupData"]];
    [summField setString: [aReport objectForKey: @"summField"]];
    summType = [[aReport objectForKey: @"summType"] intValue];
    countDup = [[aReport objectForKey: @"countDup"] boolValue];
    countBlank = [[aReport objectForKey: @"countBlank"] boolValue];
    compLevel = [[aReport objectForKey: @"compLevel"] intValue];
    summFieldType = [[aReport objectForKey: @"summFieldType"] intValue];
    if([aReport objectForKey: @"sort"] != nil)
        [sortStack addObjectsFromArray: [aReport objectForKey: @"sort"]];
    else {
        [sortStack release]; 
        sortStack = nil;
    }

}

-(BOOL) compareField: (NSString *) field type: (int) t first: (NSString *) s1
    second: (NSString *) s2 compLevel: (int) cl
{
    if(t == SRINTTYPE)
        return ([s1 intValue] == [s2 intValue])? YES : NO;
    if(t == SRREALTYPE)
        return ([s1 floatValue] == [s2 floatValue]) ? YES : NO;
    if(t == SRALPHATYPE)
        return [s1 isEqualToString: s2];
    if(t == SRDATETYPE)
    {
        return [[NSCalendarDate dateWithString:s1 calendarFormat: dateFormat]
            isEqualToDate: [NSCalendarDate dateWithString:s2 calendarFormat: dateFormat]];
    }
    if(t == SRCODETYPE)
    {
        return [self isEqualToLevel: cl first: s1 second: s2];
    }
}
-(void) printShowingPrintPanel: (BOOL) flag
{
    NSPrintInfo *printInfo = [self printInfo];
    NSPrintOperation *printOp;
    printOp = [NSPrintOperation printOperationWithView: dataTable
	printInfo: printInfo];
    [printOp setShowPanels: flag];
    [printOp runOperation];
}

#define COUNTNAME(X) 	((summType == SUMMCOUNT)? [NSString stringWithFormat: @"%@ Count",X] : [NSString stringWithFormat: @"%@ Sum",X])
#define SUMNAME(X) 	[NSString stringWithFormat: @"%@ Sum",X]
-(void) setupTable
{
 
    //delete the existing columns
    //create the right number of columns with the right headers
    //send a refresh
    
    id tc;

	tc = [dataTable tableColumns];
    FORALL(tc)
    {
	[dataTable removeTableColumn: temp];
    }
    ENDFORALL;
    
        //create new ones
    if([summData count] == 0) return;
    //make the count stuff here
//    md = [myData objectAtIndex: 0];
    MAKECOLUMN(dataTable, @"Total", @"Total");
    FORALL(groupData)
    {
        NSString *title;
        title = [temp objectForKey: @"field"];
        MAKECOLUMN(dataTable, title, title);
    }
    ENDFORALL;
    FORALL(groupData)
    {
        NSString *title;
        title = [temp objectForKey: @"field"];
        MAKECOLUMN(dataTable, COUNTNAME(title), COUNTNAME(title));
    
    }
    ENDFORALL;
    MAKECOLUMN(dataTable, COUNTNAME(@"Total"), COUNTNAME(@"Total"));
    [dataTable setAllowsColumnReordering: YES];
    [dataTable reloadData];
    
}

-(NSString *) stringValue: (NSDictionary *) record field: (NSString *) which
{

    if([which isEqualToString: @"_doc"] == YES)
    {
        return [[record objectForKey: which] name];
    }
    else if([which isEqualToString: @"_end_loc"] == YES)
    {
        return [record objectForKey: which];
    }
    else if([which isEqualToString: @"_begin_loc"] == YES)
    {
        return [record objectForKey: which];
    
    }
    else return [record objectForKey: which];
}

-(NSString *) realValue: (NSString *) ss toLevel: (int) l
{
    NSArray *mid; 
    NSMutableArray *aend;
    int i;

    if(l == 0) return [[ss copy] autorelease];
    mid = [ss componentsSeparatedByString: @">"];
    if([mid count] <= l)  return [[ss copy] autorelease];
    aend = [NSMutableArray array];
    for(i=0; i< l; i++)
    {
        [aend addObject: [[[mid objectAtIndex: i] copy] autorelease]];
    }
    return [aend componentsJoinedByString: @">"];
         
}

-(NSString *) realValue: (NSString *) ss forGroup: (NSDictionary *) dd
{
    int  l;
    
    if([[dd objectForKey: @"type"] intValue] == SRCODETYPE)
    {
        l = [[dd objectForKey: @"compLevel"] intValue];
        return [self realValue: ss toLevel: l];
        
    }
    else
   	return [[ss copy] autorelease];

}
-(void) buildSummary
{
    int fflag;
    int i,j,n,m, i1;
    NSMutableArray *currValue, *summArray;
    id currData;
    int breakpnt;
    
    if(sortStack != nil)
        [self sortData: data withStack: sortStack];
    
    currValue = [NSMutableArray array];
    summArray = [NSMutableArray array];
    fflag = 1;
    
    n = [data count];
    m = [groupData count];
    for(i = 0 ; i < n; i++)
    {
        currData = [data objectAtIndex: i];
        if(fflag)
        {
            FORALL(groupData)
            {
                [currValue addObject: [[[self stringValue: currData field: [temp objectForKey: @"field"]]
                    copy] autorelease]];
            }
            ENDFORALL;
            [currValue addObject: [[[self stringValue: currData field: summField] copy] autorelease]];
            fflag = 0;
            //loop for all summArray
            FORALL(groupData)
            {
                if (summType == SUMMCOUNT)
                {
                    [summArray addObject: [[[NSMutableNumber alloc] initWithInt:  1]autorelease]];
                }
                else
                {
                    [summArray addObject: [[[NSMutableNumber alloc] initWithString: [self stringValue: currData field: summField]] autorelease] ];
                }
            }ENDFORALL;
            if(summType == SUMMCOUNT)
                [tot inc];
            else
                [tot addString:  [self stringValue: currData field: summField]];
        }
        else
        {
            breakpnt = -1;
            //Check for break,find the lowest member of currValue to break
            FORALL(groupData)
            {
            
                if([self compareField: [temp objectForKey: @"field"] type:
                    [[temp objectForKey: @"type"] intValue]
                    first:  [self stringValue: currData field: [temp objectForKey: @"field"]]
                    second: [currValue objectAtIndex: __i] compLevel: [[temp objectForKey: @"compLevel"] intValue]] == NO )
                   {
                        breakpnt = __i;
                        break;
                    }
            }
            ENDFORALL;
            if(breakpnt>=0)
            {
                for(j = m - 1; j >= breakpnt; j--)
                {
                    NSMutableDictionary *sr = [NSMutableDictionary dictionary];
                    [sr setObject: [self realValue: [currValue objectAtIndex: j] forGroup: [groupData objectAtIndex: j]]
                        forKey: @"value"];
                   [sr setObject: [[summArray objectAtIndex: j] description]
                        forKey: @"summValue"];
                    [sr setObject: [NSNumber numberWithInt: j] forKey: @"level"];
                    [sr setObject: [[[[groupData objectAtIndex: j] objectForKey: @"field"] copy] autorelease]
                        forKey: @"field"];
                    for(i1 = 0; i1 < j; i1++)
                    {
                        [sr setObject: [self realValue: [[[currValue objectAtIndex: i1] copy] autorelease] 
                                forGroup: [groupData objectAtIndex: i1]]
                            forKey: [[groupData objectAtIndex: i1] objectForKey: @"field"]];
                    }
                    [summData addObject: sr];
                    [[summArray objectAtIndex: j] zeroInt];
                }
                
            }
            
            // this involves a compare value at the appropriate level
            //all values higher need to have summary records made and zero arrays
            //--if yes make summary and zero the the summArray arrays
            //set currValues
            {
                switch(summType)
                {
                    case SUMMCOUNT:
                        if (countBlank == NO && [[self stringValue:currData field: summField]
                                isEqualToString: @""] == YES)
                            {
                                ;
                            }
                    
                        else if(countDup == NO)
                        {
                            //need to check to see if we really do this
                            if( breakpnt <  0 && [self compareField: summField type: summFieldType
                                    first: [self stringValue: currData field: summField]
                                    second: [currValue objectAtIndex: m]
                                    compLevel: compLevel] == YES)
                            {
                            
                                    ;//don't do a thing.
                            }
                            else        
                            {
                                for(j = 0; j < m; j++){
                                    [[summArray objectAtIndex: j] inc];
                                    if(j==0)[tot inc];}
                            }
                        }
                        else
                        {
                            for(j = 0; j < m; j++){
                                [[summArray objectAtIndex: j] inc];
                                if(j==0)[tot inc];
                            }
                        }
                        break;
                    case SUMMSUM:
                           for(j = 0; j < m; j++){
                                [[summArray objectAtIndex: j] addString: [self stringValue: currData field: summField]];
                                if(j==0)[tot addString: [self stringValue: currData field: summField]];
                         }
                        
                     default:;
                }
            }
            [currValue removeAllObjects];
            FORALL(groupData)
            {
                [currValue addObject: [[[self stringValue: currData field: [temp objectForKey: @"field"]]
                    copy] autorelease]];
            }
            ENDFORALL;
            [currValue addObject: [[[self stringValue: currData field: summField] copy] autorelease]];
            
        }
    }
    for(j = m - 1; j >= 0; j--)
    {
        NSMutableDictionary *sr = [NSMutableDictionary dictionary];
        [sr setObject: [self realValue: [currValue objectAtIndex: j] forGroup: [groupData objectAtIndex: j]]
            forKey: @"value"];
        [sr setObject: [[[[groupData objectAtIndex: j] objectForKey: @"field"] copy] autorelease]
            forKey: @"field"];
        [sr setObject: [[summArray objectAtIndex: j] description]
            forKey: @"summValue"];
        [sr setObject: [NSNumber numberWithInt: j] forKey: @"level"];
        for(i1 = 0; i1 < j; i1++)
        {
            [sr setObject: [self realValue: [[[currValue objectAtIndex: i1] copy] autorelease] 
                    forGroup: [groupData objectAtIndex: i1]] forKey: 
                [[groupData objectAtIndex: i1] objectForKey: @"field"]];
        }
        [summData addObject: sr];
        [[summArray objectAtIndex: j] zeroInt];
    }
    {
        int n;
        n = [summData count];
        n++;
    }
    [self setupTable];
    [dataTable reloadData];
    [self  updateChangeCount: NSChangeDone];

}

- (NSString *)windowNibName {
    // Implement this to return a nib to load OR implement -makeWindowControllers to manually create your controllers.
    
    return @"MWSummaryReport";
}

- (NSData *)dataRepresentationOfType:(NSString *)type {
    // Implement to provide a persistent data representation of your document OR remove this and implement the file-wrapper or file path based save methods.
    NSMutableData *dd;
    NSMutableArray *ci = [[NSMutableArray alloc] init];
    int i, n;
    
    	dd = [[NSMutableData alloc] init];
    //make the count stuff here
//    md = [myData objectAtIndex: 0];
    DATASTRING(dd,  @"Total");   
    [ci addObject: @"Total"];
    FORALL(groupData)
    {
        NSString *title;
        title = [temp objectForKey: @"field"];
        DATATAB(dd);
        DATASTRING(dd, title);
        [ci addObject: title];
    }
    ENDFORALL;
    FORALL(groupData)
    {
        NSString *title;
        title = [temp objectForKey: @"field"];
        DATATAB(dd);
        DATASTRING(dd, COUNTNAME(title));
        [ci addObject: COUNTNAME(title)];
    
    }
    ENDFORALL;
    DATATAB(dd);
    DATASTRING(dd, COUNTNAME(@"Total"));
    [ci addObject: COUNTNAME(@"Total")];
    DATANL(dd);
    n = [summData count];
    for(i = 0; i <=n ; i++)
    {
        FORALL(ci)
        {
            if(__i > 0) DATATAB(dd);
            DATASTRING(dd, [self columnID: temp row: i]);
        }
        ENDFORALL;
        DATANL(dd);
    }
    [ci release];
    return dd;

}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)type {
    // Implement to load a persistent data representation of your document OR remove this and implement the file-wrapper or file path based load methods.
    return NO;
}
-(void) setDateFormat: (NSString *) df
{
    [dateFormat setString: df];
}
-(NSWindow *) window {return myWindow;}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
    int n = [summData count];
    return n+1;
}
- (id) columnID: (NSString *) col row: (int) rowIndex
{
    NSMutableDictionary *dd;
    NSString *tt ;
    if(rowIndex == [summData count] && [col isEqualToString: @"Total"])
        return @"Total";
    if(rowIndex == [summData count] && [col isEqualToString: COUNTNAME(@"Total")])
        return [tot description];
    if(rowIndex == [summData count]) return @"";
    
    dd  = [summData objectAtIndex: rowIndex];
    tt = [dd objectForKey: @"field"];
    if([col isEqualToString: COUNTNAME(tt)] == YES)
        return [dd objectForKey: @"summValue"];
    if([col isEqualToString: tt] == YES)
        return [dd objectForKey: @"value"];
    if([dd objectForKey: col] != nil) return [dd objectForKey: col];
    
    return @"";

}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
    return [self columnID: [aTableColumn identifier] row: rowIndex];
    /*
    if(rowIndex == [summData count] && [[aTableColumn identifier] isEqualToString: @"Total"])
        return @"Total";
    if(rowIndex == [summData count] && [[aTableColumn identifier] isEqualToString: COUNTNAME(@"Total")])
        return [tot description];
    if(rowIndex == [summData count]) return @"";
    dd  = [summData objectAtIndex: rowIndex];
    tt = [dd objectForKey: @"field"];
    if([[aTableColumn identifier] isEqualToString: COUNTNAME(tt)] == YES)
        return [dd objectForKey: @"summValue"];
    if([[aTableColumn identifier] isEqualToString: tt] == YES)
        return [dd objectForKey: @"value"];
    
    return @"";
    */
}
@end
