/////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2010, Frank Blumenberg
// 
// See License.txt for complete licensing and attribution information.
// Permission is hereby granted, free of charge, to any person obtaining a copy 
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
// copies of the Software, and to permit persons to whom the Software is 
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
// THE SOFTWARE.
// 
/////////////////////////////////////////////////////////////////////////////////

#import "MainViewController.h"
#import "InAppSettings.h"
#import "Settings.h"
#import "GradientButton.h"
#import "MKConnectionController.h"
#import "MKDataConstants.h"
#import "MKIpConnection.h"
#import "MKFakeConnection.h"
#import "LcdViewController.h"
#import "AnalogViewController.h"
#import "SettingsSelectionViewController.h"

#define CONNECT_SECTIONID 0

@interface MainViewController (Private)

-(void)initCellForConnectionButton:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)initCellForConnectionButtonDisconnected:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)initCellForConnectionButtonConnecting:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)initCellForConnectionButtonConnected:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)initCellForMenu:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
       
@end


//////////////////////////////////////////////////////////////////////////////////////////////
@implementation MainViewController

@synthesize versionString = _versionString;
@synthesize controllers = _controllers;

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {

  
  self.title = @"µKopter";
  //self.tableView.backgroundColor=[UIColor darkGrayColor];
  
  NSMutableArray *array = [[NSMutableArray alloc] init];

//  SettingsMainViewController* settingsController = [[SettingsMainViewController alloc] 
//                     initWithNibName:@"SettingsMainViewController" bundle:nil];

  SettingsSelectionViewController* settingsController = [[SettingsSelectionViewController alloc] 
                                            initWithStyle:UITableViewStyleGrouped];
  
  settingsController.title = NSLocalizedString(@"Settings",@"Settings controller title");
  [array addObject:settingsController];
  [settingsController release];
  
  LcdViewController* lcdController = [[LcdViewController alloc] 
                                              initWithNibName:@"LcdViewController" bundle:nil];
  
  lcdController.title = NSLocalizedString(@"LCD Menu",@"LCD Menu controller title");
  [array addObject:lcdController];
  [lcdController release];

  
  AnalogViewController* analogController = [[AnalogViewController alloc] 
                                              initWithStyle:UITableViewStylePlain];
  
  analogController.title = NSLocalizedString(@"Analog Values",@"Analog values controller title");
  [array addObject:analogController];
  [analogController release];
  
  self.controllers = array;
  [array release];
  
  connectionState=MKConnectionStateDisconnected;

  //Disable tableview scrolling.
  self.tableView.scrollEnabled = NO;

  NSNotificationCenter* nc=[NSNotificationCenter defaultCenter];

  [nc addObserver:self 
         selector:@selector(connectionRequestDidSucceed:) 
             name:MKConnectedNotification 
           object:nil];
  
  [nc addObserver:self 
         selector:@selector(disconnected:) 
             name:MKDisconnectedNotification 
           object:nil];
  
  [nc addObserver:self 
         selector:@selector(connectionRequestDidFail:) 
             name:MKDisconnectErrorNotification 
           object:nil];

  [nc addObserver:self 
         selector:@selector(versionResponse:) 
             name:MKVersionNotification
           object:nil];

  
  [super viewDidLoad];
}

-(void) viewDidAppear:(BOOL)animated {
  [self.tableView reloadData];
}

#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];
  
  // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
  
  self.versionString=nil;
  self.controllers = nil;
  [super viewDidUnload];
}

- (void)dealloc {
  [_versionString release];
  [_controllers release];
  
  [super dealloc];
}


//////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  
  if(section==CONNECT_SECTIONID)
    return 1;
  
  return connectionState==MKConnectionStateConnected?[self.controllers count]:0;
}

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
  if (section!=CONNECT_SECTIONID) 
    return nil;
  
  DLog(@"Footer for %d state %d",section,connectionState);
  
  if(connectionState==MKConnectionStateConnected && self.versionString!=nil )
    return self.versionString;
     
  return NSLocalizedString(@"Not Connected",@"Connection version string");
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  
  DLog(@"%@ state %d",indexPath,connectionState);
  
  static NSString *CellIdentifier = @"Cell";
  
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
  }
  
  if (indexPath.section==CONNECT_SECTIONID) {
    [self initCellForConnectionButton:cell forRowAtIndexPath:indexPath]; 
  }
  else {
    [self initCellForMenu:cell forRowAtIndexPath:indexPath]; 
  }
  
  return cell;
}


//////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Table cell initialization

- (void)initCellForConnectionButton:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
  cell.textLabel.text=[[NSUserDefaults standardUserDefaults] stringForKey:kHostnameKey];
  cell.selectionStyle = UITableViewCellSelectionStyleNone;

  switch (connectionState) {
    case MKConnectionStateConnected:
      [self initCellForConnectionButtonConnected:cell forRowAtIndexPath:indexPath];
      break;
    case MKConnectionStateConnecting:
      [self initCellForConnectionButtonConnecting:cell forRowAtIndexPath:indexPath];
      break;
    default:
      [self initCellForConnectionButtonDisconnected:cell forRowAtIndexPath:indexPath];
      break;
  }
}

- (void)initCellForConnectionButtonDisconnected:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
  cell.selectionStyle = UITableViewCellSelectionStyleNone;
  cell.accessoryView = nil;
  cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}

- (UIView *) initCancelButton 
{
  UIView *accView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 94, 35)];

  GradientButton *cancelButton = [[GradientButton  alloc] initWithFrame:CGRectMake(0.0, 0.0, 63.0, 33.0)];

  [cancelButton useRedDeleteStyle];
  [cancelButton setTitle:NSLocalizedString(@"Abort",@"Conncetion abort button") forState:UIControlStateNormal];
  [cancelButton addTarget:self action:@selector(userDidCancelLastConnectRequest) forControlEvents:UIControlEventTouchDown];
  cancelButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];

  UIActivityIndicatorView *gear = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
  gear.frame = CGRectMake(68.0, 5.5, 22.0, 22.0);
  [gear startAnimating];

  [accView addSubview:gear];
  [accView addSubview:cancelButton];
  return accView;
}

- (void)initCellForConnectionButtonConnecting:(UITableViewCell *)cell
{
  UIView *accView;
  accView = [self initCancelButton];

  cell.accessoryView = accView;
  cell.accessoryType = UITableViewCellAccessoryNone;
  [accView release];
}

- (UIView *) initStopButton 
{
  UIView *accView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 63, 35)];
  
  GradientButton *stoplButton = [[GradientButton  alloc] initWithFrame:CGRectMake(0.0, 0.0, 63.0, 33.0)];

  [stoplButton useAlertStyle];
  [stoplButton setTitle:NSLocalizedString(@"Stop",@"Conncetion stop button") forState:UIControlStateNormal];
  [stoplButton addTarget:self action:@selector(userDidDisconnect) forControlEvents:UIControlEventTouchDown];
  stoplButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
  
  [accView addSubview:stoplButton];
  return accView;
}

- (void)initCellForConnectionButtonConnected:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{
  cell.detailTextLabel.text=@"Connected";
  
  UIView *accView;
  accView = [self initStopButton];
  
  cell.accessoryView = accView;
  cell.accessoryType = UITableViewCellAccessoryNone;
  [accView release];
}

//-----------------------------------------------------------------------

- (void)initCellForMenu:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath  
{
  // Configure the cell
  NSUInteger row = [indexPath row];
  UIViewController *controller =  [_controllers objectAtIndex:row];
 
  cell.textLabel.text = controller.title;
  cell.accessoryView = nil;
  cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

//////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Connection status actions (Statemachine)

- (void)userDidDisconnect;
{
  [[MKConnectionController sharedMKConnectionController] stop];
}

- (void)userDidCancelLastConnectRequest;
{
  [[MKConnectionController sharedMKConnectionController] stop];
  connectionState=MKConnectionStateDisconnected;
  [self.tableView reloadData];
}
- (void)connectionRequestDidFail:(NSNotification *)aNotification;
{
  NSError* err = [[aNotification userInfo] objectForKey:@"error"];
  
  UIAlertView *alert = [[UIAlertView alloc] 
                        initWithTitle:NSLocalizedString(@"Server error", @"Server error")
                        message:[err localizedDescription] 
                        delegate:self 
                        cancelButtonTitle:@"Ok" 
                        otherButtonTitles:nil];
  [alert show];
  [alert release];
  
  [self.navigationController popToRootViewControllerAnimated:YES]; 
  
  connectionState=MKConnectionStateDisconnected;
  [self.tableView reloadData];
}
- (void)connectionRequestDidSucceed:(NSNotification *)aNotification;
{
  DLog(@"Got connected");

  connectionState=MKConnectionStateConnected;
  [self.tableView beginUpdates];
  [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1]  withRowAnimation:UITableViewRowAnimationFade];
  [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:CONNECT_SECTIONID]  withRowAnimation:UITableViewRowAnimationNone];
  [self.tableView endUpdates];
}
- (void)disconnected:(NSNotification *)aNotification;
{
  connectionState=MKConnectionStateDisconnected;
  [self.tableView beginUpdates];
  [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1]  withRowAnimation:UITableViewRowAnimationBottom];
  [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:CONNECT_SECTIONID]  withRowAnimation:UITableViewRowAnimationNone];
  [self.tableView endUpdates];
}

- (void)versionResponse:(NSNotification *)aNotification;
{
  self.versionString = [[MKConnectionController sharedMKConnectionController]longVersionForAddress:MKAddressFC];
  
  [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:CONNECT_SECTIONID]  withRowAnimation:UITableViewRowAnimationNone];
}

//////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Table view delegate

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{

  if (indexPath.section==CONNECT_SECTIONID) {
    return (connectionState==MKConnectionStateDisconnected)?indexPath:nil;
  }
  
  return (connectionState==MKConnectionStateConnected)?indexPath:nil;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  
  if (indexPath.section==CONNECT_SECTIONID && connectionState==MKConnectionStateDisconnected) {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [self initCellForConnectionButtonConnecting:cell];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
                                                                 
    [[MKConnectionController sharedMKConnectionController] start];
  }
  else {
    
    NSUInteger row = [indexPath row];
    UIViewController* controller=[self.controllers objectAtIndex:row];
    
    [self.navigationController pushViewController:controller animated:YES];
  }

}


- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
  
  if( [indexPath section]==0 && [indexPath row]==0 ) {
    InAppSettingsViewController *settings = [[InAppSettingsViewController alloc] init];
    [self.navigationController pushViewController:settings animated:YES];
  }
}


@end

