Source

CS193P Assignment 1 / Calculator / CalculatorViewController.m

Full commit
//
//  CalculatorViewController.m
//  Calculator
//
//  Created by Jay Yu on 29/06/12.
//  Copyright (c) 2012 JayYu.com. All rights reserved.
//

#import "CalculatorViewController.h"
#import "CalculatorBrain.h"

@interface CalculatorViewController ()
@property (nonatomic, strong) CalculatorBrain *brain;
@property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber;
@property (nonatomic, strong) NSDictionary *testVariableValues;
@end

@implementation CalculatorViewController

@synthesize brain = _brain;
@synthesize display = _display;
@synthesize history = _history;
@synthesize variablesDisplay = _variablesDisplay;
@synthesize userIsInTheMiddleOfEnteringANumber = _userIsInTheMiddleOfEnteringANumber;
@synthesize testVariableValues = _testVariableValues;

- (CalculatorBrain *)brain
{
    if (!_brain) {
        _brain = [[CalculatorBrain alloc] init];
    }
    return _brain;
}

- (NSDictionary *)testVariableValues
{
    if (!_testVariableValues) {
        _testVariableValues = [[NSDictionary alloc] init];
    }
    return _testVariableValues;
}

- (void)appendHistory:(NSString *)aString;
{
    // Implements Required Task #4, Assignment 1
    if (! self.history.text) {
        self.history.text = @"";
    } else {
        self.history.text = [self.history.text stringByAppendingString:@" "];
    }

    if ([aString isEqualToString:@"="]) {
        // Extra Credit #2: put an "=" at the end of text label
        // Remove extraneous "=" already in history
        self.history.text = [self.history.text stringByReplacingOccurrencesOfString:@" ="
                                                                         withString:@""];
    }
    self.history.text = [self.history.text stringByAppendingString:aString];

    // Limit no. of characters in history so that font size of label will not
    // get smaller and smaller.
    NSUInteger length = [self.history.text length];
    NSUInteger limit = 38;
    if (length >= limit) {
        self.history.text = [self.history.text substringFromIndex:length - limit];
    }

}

- (IBAction)digitPressed:(UIButton *)sender
{
    NSString *digit = [sender currentTitle];
    if ([digit isEqualToString:@"."]) {
        // handle special case for decimal point
        if (self.userIsInTheMiddleOfEnteringANumber) {
            NSRange range = [self.display.text rangeOfString:@"."];
            if (range.location == NSNotFound) {
                self.display.text = [self.display.text stringByAppendingString:digit];
            }
        } else {
            // shortcut for user: start entering an operand with "." will
            // automatically enter "0."
            self.display.text = @"0.";
            self.userIsInTheMiddleOfEnteringANumber = YES;
        }
    } else {
        if (self.userIsInTheMiddleOfEnteringANumber) {
            self.display.text = [self.display.text stringByAppendingString:digit];
        } else {
            self.display.text = digit;
            if (! [digit isEqualToString:@"0"]) {
                self.userIsInTheMiddleOfEnteringANumber = YES;
            }
        }
    }
}

- (IBAction)enterPressed
{
    [self.brain pushOperand:[self.display.text doubleValue]];
    self.history.text = [CalculatorBrain descriptionOfProgram:self.brain.program];
    self.userIsInTheMiddleOfEnteringANumber = NO;
}

- (IBAction)operationPressed:(UIButton *)sender
{
    if (self.userIsInTheMiddleOfEnteringANumber) {
        [self enterPressed];
    }
    NSString *operation = sender.currentTitle;
    double result = [self.brain performOperation:operation];
    self.history.text = [CalculatorBrain descriptionOfProgram:self.brain.program];
    self.display.text = [NSString stringWithFormat:@"%g", result];

//    [self appendHistory:@"="];
}

- (IBAction)variablePressed:(UIButton *)sender
{
    NSString *variable = sender.currentTitle;
    [self.brain pushVariable:variable];
    self.history.text = [CalculatorBrain descriptionOfProgram:self.brain.program];
}

- (IBAction)allClear
{
    [self.brain clearStates];
    self.display.text = @"0";
    self.history.text = @"";
    self.userIsInTheMiddleOfEnteringANumber = NO;
}

- (IBAction)backspacePressed
{
    NSUInteger length = [self.display.text length];
    if (length > 0) {
        self.display.text = [self.display.text substringToIndex:length - 1];
    } else {
        self.userIsInTheMiddleOfEnteringANumber = NO;
        self.display.text = @"0";
    }
}

- (IBAction)invertSignPressed
{
    double result = 0;
    if (self.userIsInTheMiddleOfEnteringANumber) {
        // modify in-place the number currently in the display.
        result = [self.display.text doubleValue];
        if (result != 0) {
            result = result * -1;
        }
        self.display.text = [NSString stringWithFormat:@"%g", result];
    } else {
        // implement +/- as an operation
        [self.brain performOperation:@"+/-"];
    }
}

- (IBAction)testPressed:(UIButton *)sender
{
    NSString *testNumber = sender.currentTitle;

    if ([@"Test 1" isEqualToString:testNumber]) {
        self.testVariableValues = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithDouble:9.23], @"x", 
                                   [NSNumber numberWithDouble:-20], @"y", 
                                   [NSNumber numberWithDouble:0], @"z", nil]; 
    }

    if ([@"Test 2" isEqualToString:testNumber]) {
        self.testVariableValues = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithDouble:-2.11], @"x", 
                                   [NSNumber numberWithDouble:38.000], @"y", 
                                   [NSNumber numberWithDouble:0.18], @"z", nil]; 
    }

    if ([@"Test 3" isEqualToString:testNumber]) {
        self.testVariableValues = nil; 
        self.variablesDisplay.text = @"Variable not set";
        return;
    }
    
    NSMutableArray *varList = [[NSMutableArray alloc] init];
    for (id variable in [CalculatorBrain variablesUsedInProgram:self.brain.program]) {
        [varList addObject:[NSString stringWithFormat:@"%@ = %@", variable, [self.testVariableValues objectForKey:variable]]];        
    }
    self.variablesDisplay.text = [varList componentsJoinedByString:@", "];
}

- (void)viewDidUnload {
    self.history = nil;
    self.variablesDisplay = nil;
    self.testVariableValues = nil; 
    [self setVariablesDisplay:nil];
    [super viewDidUnload];
}
@end