//
//  MWKappa.m
//  TEST2
//
//  Created by matthew on Thu Aug 14 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//
#import "tams.h"
#import "MWKappa.h"
#import "tamsutils.h"
#define COLWIDTH 90.0
@implementation MWKappa

-(id) init
{
    [super init];
    fileTitles = [[NSMutableString alloc] init];
    answers = [[NSMutableArray alloc] init];
    return self;
}

-(void) dealloc
{
    [ef release];
    [fileTitles release];
    [answers release];
   [ myKMatrix release];
   [super dealloc];
}
- (NSString *)windowNibName {
    // Implement this to return a nib to load OR implement -makeWindowControllers to manually create your controllers.
    return @"kappa";
}

- (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;
        NSNumber *e;
        float ee;

    int i, n, cnt;
    cnt = [hotCodeList count];
    dd = [[NSMutableData alloc] init];
    //print the top
    DATASTRING(dd, fileTitles); 
    DATANL(dd);
    DATASTRING(dd, [NSString stringWithFormat: @"Cohen's kappa = %.3f; %d agreements/%d opportunities (%.3f)", kappa, agreements, totCount, ((float) agreements)/totCount]);
    DATANL(dd);
    FORALL(hotCodeList)
    {
        DATATAB(dd);
        DATASTRING(dd, temp);
    }
    ENDFORALL;
    DATATAB(dd); DATASTRING(dd,@"EF");
    DATATAB(dd); DATASTRING(dd,@"Total");
    DATANL(dd);
    
    //Go through the hotcode list
    for(i = 0; i < cnt; i++)
    {
    //print the code name
        DATASTRING(dd, [hotCodeList objectAtIndex: i]);
    //print the data
        FORALL(hotCodeList)
        {
             DATATAB(dd);
            DATASTRING(dd, [NSString stringWithFormat: @"%d", [myKMatrix intForKey1: 
                [hotCodeList objectAtIndex: i] key2: temp]]);
            
            
        }
        ENDFORALL;
        e = [ef objectForKey: [hotCodeList objectAtIndex: i]];
        if(e == nil)
            ee = 0.0;
        else
            ee = [e floatValue];
        //we're on a diagonal
        DATATAB(dd);
        DATASTRING(dd, [NSString stringWithFormat: @"%.3f", ee]);
        DATATAB(dd);
        DATASTRING(dd ,[NSString stringWithFormat: @"%d", [myKMatrix sumForKey1: [hotCodeList objectAtIndex: i]]]);

        DATANL(dd);
    }
    DATASTRING(dd, @"Total");
    
    FORALL(hotCodeList)
    {
        DATATAB(dd);
         DATASTRING(dd, [NSString stringWithFormat: @"%d", [myKMatrix sumForKey2: temp]]);
    }
    ENDFORALL;
    DATATAB(dd);
    DATASTRING(dd, [NSString stringWithFormat: @"%.3f", effAgSum]);
    DATATAB(dd);
    DATASTRING(dd, [NSString stringWithFormat: @"%d", totCount]);
    DATANL(dd);DATANL(dd);
    
    //summary of the results
    DATASTRING(dd, @"Item\tCoder 1\tCoder 2\n");
    for(n = 1; n<= totCount; n++)
    {
        NSString *tmp1, *tmp2;
        NSMutableDictionary *temp;
        
        temp = [answers objectAtIndex: n-1];
        
        DATASTRING(dd, [NSString stringWithFormat: @"%d\t%@\t%@\n",
            n, 
            (((tmp1 = [temp objectForKey: @"alpha"]) != nil)? tmp1: @""), 
            (((tmp2 = [temp objectForKey: @"beta"]) != nil)? tmp2: @"")]);
    
    }
    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 YES;
}
-(void) buildKappa
{
    NSArray *rows;
    NSArray *mf;
    int qcnt, tcnt;
    float effAg;
    ctQChar *q;

    //make an array of the right codes based on n
 #ifdef levels   
    FORALL(hcl)
    {
        if(codeLevel(temp) <= lvl)
            [realCodeList addObject: [[temp copy] autorelease]];
    }
    ENDFORALL;
#endif
    myKMatrix = [[MWDoubleDictionary alloc] init];
    ef = [[NSMutableDictionary alloc] init];
    mf = [tce hotFileList];
    [fileTitles setString: [NSString stringWithFormat: @"%@ x %@", [[mf objectAtIndex: 0] name],
        [[mf objectAtIndex: 1] name]]];
    [theFileTitle setStringValue: fileTitles];
    //initialize a count
    qcnt = 0;
    tcnt = 0; //a flag for which coder it is
    //first time through make an array
    theDData = [[NSMutableDictionary alloc] init];
    q = [[ctQChar alloc] init];
    
    [answers addObject: [NSMutableDictionary dictionary]];
    while([tce scanNext: q] != ENDOFALLFILES)
    {
	if([q tokentype] == TOKEN)
	{
		//[theDData setObject: [NSMutableDictionary dictionary] forKey: [[[q buff] copy] autorelease]];
            if(tcnt == 0)
                [[answers objectAtIndex: qcnt] setObject: [[[q buff] copy] autorelease] forKey: @"alpha"];
            else
                [[answers objectAtIndex: qcnt] setObject: [[[q buff] copy] autorelease] forKey: @"beta"];
	}
        if([q tokentype] == META)
        {
            if([[q buff] isEqualToString: @"endsection"])
            {
                [answers addObject:  [NSMutableDictionary dictionary]];
                qcnt++;
            }
            
            if([[q buff] isEqualToString: @"end"])
            {
                //tot = qcnt;
                qcnt = 0;
                tcnt++;
                
            }
        }
    }

    
    //then convert the dictionary:
    FORALL(answers)
    {
        if([temp objectForKey: @"alpha"] != nil && [temp objectForKey: @"beta"] != nil)
            [myKMatrix incKey1: [temp objectForKey: @"alpha"]
                key2: [temp objectForKey: @"beta"]];
    }
    ENDFORALL;
    //for each alpha code add it to a dictionary with a dictionary as the object
    //for each beta make it the key of the second dictionary and an NSNumber as the count
    
    //expected frequency of agreement rowsum*colsum/tot;
    agreements = [myKMatrix diagSum];
    rows = [myKMatrix firstKeys];
    effAgSum = 0.0;
    totCount = 0;
    FORALL(rows)
    {
        totCount += [myKMatrix sumForKey1: temp];
    }
    ENDFORALL;
    
    FORALL(rows)
    {
        int colCount;
        int rowCount = [myKMatrix sumForKey1: temp];
        colCount = [myKMatrix sumForKey2: temp];
        effAg = rowCount * colCount;
        effAg /= totCount;
//        effAg = ((float) rowCount) *colCount /((float) agreements);
        [ef setObject: [NSNumber numberWithFloat: effAg] forKey: temp];
        effAgSum += effAg;
    }
    ENDFORALL;
    kappa = (agreements - effAgSum)/(float)(totCount - effAgSum);
    [theMessage setStringValue: [NSString stringWithFormat: @"Cohen's kappa = %.3f; %d agreements/%d opportunities (%.3f)", kappa, agreements, totCount, ((float) agreements)/totCount]];
    [self setupTable];
    [theTable reloadData];
	[ansTable reloadData];
    [self updateChangeCount: NSChangeDone];
    
}

-(void) setupTable
{
    NSTableColumn *t;
 
    //make it the first column
	t = [[NSTableColumn alloc] initWithIdentifier: @".Codes"];
	[t setWidth: COLWIDTH];
	[theTable addTableColumn: t];
	[[t headerCell] setStringValue: @"Codes"];
    //Add a column for each and
	FORALL(hotCodeList)
	{
	    t = [[NSTableColumn alloc] initWithIdentifier: temp];
		[t setWidth: COLWIDTH];
	    [theTable addTableColumn: t];
	    [[t headerCell] setStringValue: temp];
	}ENDFORALL;
    //make it the first column
	t = [[NSTableColumn alloc] initWithIdentifier: @".EF"];
	[t setWidth: COLWIDTH];
	[theTable addTableColumn: t];
	[[t headerCell] setStringValue: @"EF"];
        
	t = [[NSTableColumn alloc] initWithIdentifier: @".RTotals"];
	[t setWidth: COLWIDTH];
	[theTable addTableColumn: t];
	[[t headerCell] setStringValue: @"Total"];
        
	    
}
/* table portion */
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
        if(aTableView == ansTable) return totCount;
        
	return [hotCodeList count] + 1;

}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn: (NSTableColumn *)aTableColumn row:(int)rowIndex
{
        NSNumber *e;
        int cnt;
        float ee;
        cnt = [hotCodeList count];
        if(aTableView == ansTable)
        {
		NSLog(@"Building back table\n");
            if([[aTableColumn identifier] isEqualToString: @"Item"] == YES)
            {
                //return [NSString stringWithFormat: @"%d", rowIndex+1];
		NSLog(@"returning %d\n",rowIndex+1);
                return [NSNumber numberWithInt: rowIndex+1];
            }
            else if([[aTableColumn identifier] isEqualToString: @"Coder 1"] == YES)
            {
                return [[answers objectAtIndex: rowIndex] objectForKey: @"alpha"];
            }
        
            else if([[aTableColumn identifier] isEqualToString: @"Coder 2"] == YES)
            {
                return [[answers objectAtIndex: rowIndex] objectForKey: @"beta"];
            }
        
        }
	if([[aTableColumn identifier] isEqualToString: @".Codes"] 
	    == YES)
	{
            if(rowIndex >= cnt)
            {
                return @"Total";
            }
	    return [hotCodeList objectAtIndex: rowIndex];
	}
	if([[aTableColumn identifier] isEqualToString: @".RTotals"] == YES)
        {
            if(rowIndex < cnt)
                return [NSNumber numberWithInt: [myKMatrix sumForKey1: [hotCodeList objectAtIndex: rowIndex]]];
            else
                return [NSNumber numberWithInt: totCount];
        }
	if([[aTableColumn identifier] isEqualToString: @".EF"] == YES)
        {
            if(rowIndex < cnt)
            {
                e = [ef objectForKey: [hotCodeList objectAtIndex: rowIndex]];
                if(e == nil)
                    ee = 0.0;
                else
                    ee = [e floatValue];
                return [NSString stringWithFormat: @"%.3f", ee];
            }
            else return [NSString stringWithFormat: @"%.3f", effAgSum];
        
        }
        if(rowIndex >= cnt)
        {
            return [NSNumber numberWithInt: [myKMatrix sumForKey2: [aTableColumn identifier]]];
	}
        
        return [NSString stringWithFormat: @"%d", [myKMatrix intForKey1: 
            [hotCodeList objectAtIndex: rowIndex] key2: [aTableColumn identifier]]];
        
        


}



@end
