Fix compile errors
[pithos-ios] / Classes / LBNodeViewController.m
1 //
2 //  LBNodeViewController.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 6/27/11.
6 //  Copyright 2011 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "LBNodeViewController.h"
10 #import "LoadBalancerNode.h"
11 #import "LoadBalancer.h"
12 #import "UIViewController+Conveniences.h"
13 #import "RSTextFieldCell.h"
14 #import "UIColor+MoreColors.h"
15 #import "OpenStackAccount.h"
16 #import "AccountManager.h"
17 #import "APICallback.h"
18 #import "LoadBalancerViewController.h"
19
20 #define kConditionSection 0
21 #define kEnabled 0
22 #define kDraining 1
23 #define kDisabled 2
24
25 #define kRemoveNode 1
26
27 @implementation LBNodeViewController
28
29 @synthesize node, loadBalancer, account, lbViewController, lbIndexPath;
30
31 - (id)initWithNode:(LoadBalancerNode *)n loadBalancer:(LoadBalancer *)lb account:(OpenStackAccount *)a {
32     self = [self initWithStyle:UITableViewStyleGrouped];
33     if (self) {
34         self.node = n;
35         self.loadBalancer = lb;
36         self.account = a;
37     }
38     return self;
39 }
40
41 - (void)dealloc {
42     [node release];
43     [loadBalancer release];
44     [account release];
45     [spinners release];
46     [lbIndexPath release];
47     [super dealloc];
48 }
49
50 #pragma mark - View lifecycle
51
52 - (void)viewDidLoad {
53     [super viewDidLoad];
54     self.navigationItem.title = self.node.address;
55     
56     NSMutableArray *s = [[NSMutableArray alloc] initWithCapacity:3];
57     for (int i = 0; i < 3; i++) {
58         UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
59         spinner.hidesWhenStopped = YES;
60         [s addObject:spinner];
61         [spinner release];
62     }
63     spinners = [[NSArray alloc] initWithArray:s];
64     [s release];
65     
66     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
67         [self addDoneButton];
68     }
69     
70     editable = YES;
71     
72     // if there is only one enabled node on the load balancer, it can't be
73     // edited or deleted
74     if ([self.loadBalancer.nodes count] == 1) {
75         editable = NO;
76     } else {
77         NSInteger enabledCount = 0;
78         for (LoadBalancerNode *n in self.loadBalancer.nodes) {
79             if ([n.condition isEqualToString:@"ENABLED"]) {
80                 enabledCount++;
81             }
82         }
83         
84         if (enabledCount <= 1 && [self.node.condition isEqualToString:@"ENABLED"]) {
85             editable = NO;
86         }
87     }
88 }
89
90 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
91     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (interfaceOrientation == UIInterfaceOrientationPortrait);
92 }
93
94 #pragma mark - Table view data source
95
96 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
97     return 2;
98 }
99
100 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
101     if (section == kConditionSection) {
102         return 3;
103     } else {
104         return 1;
105     }
106 }
107
108 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
109     if (section == kConditionSection) {
110         if (editable) {
111             return @"Draining nodes are disabled after all current connections are completed.";
112         } else {
113             return @"There must be at least one enabled node for this load balancer.";
114         }
115     } else {
116         return @"";
117     }
118 }
119
120 - (UITableViewCell *)removeNodeCell {
121     static NSString *CellIdentifier = @"RemoveNodeCell";    
122     UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
123     if (cell == nil) {
124         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
125         cell.textLabel.textAlignment = UITextAlignmentCenter;
126         cell.textLabel.textColor = editable ? [UIColor value1DetailTextLabelColor] : [UIColor lightGrayColor];
127         cell.textLabel.text = @"Remove Node";
128         cell.selectionStyle = editable ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone;
129         
130     }
131     return cell;
132 }
133
134 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
135     if (indexPath.section == kRemoveNode) {
136         return [self removeNodeCell];
137     } else {
138         static NSString *CellIdentifier = @"Cell";
139         
140         UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
141         if (cell == nil) {
142             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];            
143         }
144         
145         cell.selectionStyle = editable ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone;
146         
147         switch (indexPath.row) {
148             case kEnabled:
149                 cell.textLabel.text = @"Enabled";
150                 cell.textLabel.textColor = [UIColor blackColor];
151                 break;
152             case kDraining:
153                 cell.textLabel.text = @"Draining";
154                 cell.textLabel.textColor = editable ? [UIColor blackColor] : [UIColor lightGrayColor];
155                 break;
156             case kDisabled:
157                 cell.textLabel.text = @"Disabled";
158                 cell.textLabel.textColor = editable ? [UIColor blackColor] : [UIColor lightGrayColor];
159                 break;
160             default:
161                 break;
162         }
163         
164         if ([self.node.condition isEqualToString:[cell.textLabel.text uppercaseString]]) {
165             cell.accessoryType = UITableViewCellAccessoryCheckmark;
166             cell.accessoryView = nil;
167         } else {
168             cell.accessoryType = UITableViewCellAccessoryNone;
169             cell.accessoryView = [spinners objectAtIndex:indexPath.row];
170         }
171         
172         return cell;
173     }
174 }
175
176 #pragma mark - Table view delegate
177
178 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
179     if (editable) {
180         if (indexPath.section == kConditionSection) {
181             
182             if ([self.loadBalancer shouldBePolled]) {
183                 [self alert:nil message:@"This node can not be changed until the load balancer is in an active state."];                
184                 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
185             } else {
186                 NSString *oldCondition = [NSString stringWithString:self.node.condition];
187                 
188                 switch (indexPath.row) {
189                     case kEnabled:
190                         self.node.condition = @"ENABLED";
191                         break;
192                     case kDraining:
193                         self.node.condition = @"DRAINING";
194                         break;
195                     case kDisabled:
196                         self.node.condition = @"DISABLED";
197                         break;
198                     default:
199                         break;
200                 }
201                 
202                 // make the API call
203                 NSString *endpoint = [self.account loadBalancerEndpointForRegion:self.loadBalancer.region];
204                 [[spinners objectAtIndex:indexPath.row] startAnimating];
205                 APICallback *callback = [self.account.manager updateLBNode:self.node loadBalancer:self.loadBalancer endpoint:endpoint];
206                 
207                 [callback success:^(OpenStackRequest *request) {
208                     [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
209                     [NSTimer scheduledTimerWithTimeInterval:0.35 target:self.tableView selector:@selector(reloadData) userInfo:nil repeats:NO];
210                 } failure:^(OpenStackRequest *request) {
211                     self.node.condition = oldCondition;
212                     [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
213                     [NSTimer scheduledTimerWithTimeInterval:0.35 target:self.tableView selector:@selector(reloadData) userInfo:nil repeats:NO];
214                     [self alert:@"There was a problem changing the condition of this node." request:request];
215                 }];        
216             }
217             
218         } else {
219             UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure you want to remove this node from the load balancer?" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil];
220             sheet.delegate = self;
221             [sheet showInView:self.view];
222             [sheet release];
223         }
224     }
225 }
226
227 #pragma mark - Action Sheet Delegate
228
229 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
230     if (buttonIndex == 0) {
231         NSString *endpoint = [self.account loadBalancerEndpointForRegion:self.loadBalancer.region];
232         APICallback *callback = [self.account.manager deleteLBNode:self.node loadBalancer:self.loadBalancer endpoint:endpoint];
233         [callback success:^(OpenStackRequest *request) {
234             [self.navigationController popViewControllerAnimated:YES];
235         } failure:^(OpenStackRequest *request) {
236             [self alert:@"There was a problem removing this node." request:request];
237         }];
238     }
239     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:kRemoveNode];
240     [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
241 }
242
243 #pragma mark - Button Handlers
244
245 - (void)doneButtonPressed:(id)sender {
246     [self dismissModalViewControllerAnimated:YES];
247     [self.lbViewController.tableView deselectRowAtIndexPath:self.lbIndexPath animated:YES];
248 }
249
250 @end