//
//  EditMetadataViewController.m
//  pithos-ios
//
// Copyright 2011 GRNET S.A. All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
// 
//   1. Redistributions of source code must retain the above
//      copyright notice, this list of conditions and the following
//      disclaimer.
// 
//   2. Redistributions in binary form must reproduce the above
//      copyright notice, this list of conditions and the following
//      disclaimer in the documentation and/or other materials
//      provided with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// The views and conclusions contained in the software and
// documentation are those of the authors and should not be
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.

#import "EditMetadataViewController.h"
#import "AccountManager.h"
#import "UIViewController+Conveniences.h"
#import "FolderViewController.h"
#import "Folder.h"
#import "PithosUtilities.h"



@implementation EditMetadataViewController


@synthesize container, account, object;

@synthesize metadataKey;
@synthesize metadataValue;
@synthesize removeMetadataEnabled, objectIsFolder, folderViewController, objectIsContainer;

#define kMetadata 0 
#define kSaveMedata 1
#define kDeleteMetadata 2


- (void)dealloc
{
    [account release];
    [container release];
    [object release];
    [metadataKey release];
    [metadataValue release];
    [super dealloc];
}

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

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (void)viewWillAppear:(BOOL)animated
{    
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == kMetadata)
        return 2;
    else
        return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
                
    if (indexPath.section == kMetadata) {
        UITextField *textField = nil;
        for (id subView in cell.contentView.subviews) {
            if ([subView isKindOfClass:[UITextField class]]) {
                textField = (UITextField *)subView;
            }
        }
        
        if (textField == nil) {
            CGRect bounds = [cell.contentView bounds];
            CGRect rect = CGRectInset(bounds, 10.0, 10.0);                        
            textField = [[UITextField alloc] initWithFrame:rect];
            [textField setFrame:rect];
        }
        [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
        [textField setBackgroundColor:[UIColor clearColor]];
        [textField setOpaque:YES];
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
        [textField setDelegate:self];
        textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        if (indexPath.row == 0) {
            [textField setReturnKeyType:UIReturnKeyNext];
            textField.placeholder = @"Key";
            textField.text = self.metadataKey;
            textField.tag = 0;
        }
        else if (indexPath.row == 1) {
            textField.placeholder = @"Value";
            textField.text = self.metadataValue;
            textField.tag = 1;
        }
            
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        [cell.contentView addSubview:textField];
    }
    else if (indexPath.section == kSaveMedata) 
        cell.textLabel.text = @"Save";
    else if (indexPath.section == kDeleteMetadata)
        cell.textLabel.text = @"Remove";
    
    return cell;
}


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    
    if (indexPath.section != kMetadata)
        [self.view endEditing:YES];
    
    NSString *activityMessage;
    NSIndexPath *keyCellIndexPath;
    NSIndexPath *valueCellIndexPath;
    UITableViewCell *cell;
    
    switch (indexPath.section) {
        case kSaveMedata:
            keyCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kMetadata];
            cell = [self.tableView cellForRowAtIndexPath:keyCellIndexPath];
            UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
            newMetadataKey = textField.text;
        
            if ([newMetadataKey length] == 0
                || [[newMetadataKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
                return;
            }
            
            valueCellIndexPath = [NSIndexPath indexPathForRow:1 inSection:kMetadata];
            cell = [self.tableView cellForRowAtIndexPath:valueCellIndexPath];
            textField = [[cell.contentView subviews] objectAtIndex:0];
            newMetadataValue = textField.text;
            
            [object.metadata removeObjectForKey:metadataKey];
            [object.metadata setObject:newMetadataValue forKey:newMetadataKey];
            
            if (objectIsFolder && ![PithosUtilities isContentTypeDirectory:object.contentType]) {
                if ([folderViewController.folder.objects objectForKey:object.name]) {
                    NSString *alertMessage = [NSString stringWithFormat:@"In order to apply the changes in '%@', the object at the same path must be replaced. Continue?",object.name];
                    NSString *alertTitle = @"Apply changes";
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle
                                                                    message:alertMessage
                                                                   delegate:self
                                                          cancelButtonTitle:@"Cancel"
                                                          otherButtonTitles:@"OK", nil];
                    [alert show];
                    return;
                } else {
                    activityMessage = @"Saving metadata...";
                    activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
                    [activityIndicatorView addToView:self.view];
                    
                    object.name = object.fullPath;
                    object.contentType = @"application/directory";
                    object.data = [NSData data];
                    [self addNewFolderRequestObservers];
                    [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];  
                    return;
                }
            }
            
            activityMessage = @"Saving metadata";
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
            [activityIndicatorView addToView:self.view];

            [self.account.manager writeObjectMetadata:container object:object];
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
                                                                                object:object
                                                                                 queue:[NSOperationQueue mainQueue]
                                                                            usingBlock:^(NSNotification *notification)
                               {
                                   self.metadataKey = newMetadataKey;
                                   self.metadataValue = newMetadataValue;
                                   removeMetadataEnabled = YES;
                                   [self.tableView reloadData];
                                   [activityIndicatorView removeFromSuperviewAndRelease];
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                                   if (objectIsContainer) {
                                       container.metadata = object.metadata;
                                       [self.account.containers setObject:container forKey:container.name];
                                   }
                                   [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
                               }];
            
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
                                                                                object:object 
                                                                                 queue:[NSOperationQueue mainQueue] 
                                                                            usingBlock:^(NSNotification *notification)
                               {
                                   [object.metadata removeObjectForKey:newMetadataKey];
                                   [object.metadata setObject:metadataValue forKey:metadataKey];
                                   [activityIndicatorView removeFromSuperviewAndRelease];
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                                   [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
                                   
                                   [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
                               }];
            
            break;
        case kDeleteMetadata:
            activityMessage = @"Deleting metadata";
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
            [activityIndicatorView addToView:self.view];

            [object.metadata removeObjectForKey:metadataKey];
            [self.account.manager writeObjectMetadata:container object:object];
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
                                                                                object:object
                                                                                 queue:[NSOperationQueue mainQueue]
                                                                            usingBlock:^(NSNotification *notification)
                               {
                                   [activityIndicatorView removeFromSuperviewAndRelease];
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                                   self.metadataKey = @"";
                                   self.metadataValue = @"";
                                   removeMetadataEnabled = NO;
                                   [self.tableView reloadData];
                                   if (objectIsContainer) {
                                       container.metadata = object.metadata;
                                       [self.account.containers setObject:container forKey:container.name];
                                   }
                                   [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
                               }];
            
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
                                                                                object:object 
                                                                                 queue:[NSOperationQueue mainQueue] 
                                                                            usingBlock:^(NSNotification *notification)
                               {
                                   [object.metadata setObject:metadataValue forKey:metadataKey];
                                   [activityIndicatorView removeFromSuperviewAndRelease];
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                                   [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
                                   
                                   [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
                               }];

            break;
    }
}

#pragma mark - Alertview delegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        NSString *activityMessage = @"Applying permissions...";
        
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
        [activityIndicatorView addToView:self.view];
        
        object.name = object.fullPath;
        object.contentType = @"application/directory";
        object.data = [NSData data];
        [self addNewFolderRequestObservers];
        [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];        
        
    } else {
        [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
    }
}

#pragma mark - Textfield delegate


- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    
    if ([textField returnKeyType] == UIReturnKeyNext)
    {
        if ([textField.text length] == 0
            || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
            [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
        }

        NSInteger nextTag = [textField tag] + 1;
        UIView *nextTextField = [self.tableView viewWithTag:nextTag];
        [nextTextField becomeFirstResponder];
    }
    else
    {
        [textField resignFirstResponder];
    }
    
    return YES;
}

#pragma mark - add observers

- (void)addNewFolderRequestObservers {
    addFolderSuccessObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object 
                                                                                  queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
                                {
                                    Folder *newFolder = [[Folder alloc] init];
                                    newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
                                    newFolder.parent = folderViewController.folder;
                                    newFolder.sharing = folderViewController.folder.sharing;
                                    newFolder.metadata = object.metadata;
                                    [folderViewController.folder.folders setObject:newFolder forKey:newFolder.name];
                                    [activityIndicatorView removeFromSuperviewAndRelease];
                                    [newFolder release];
                                    self.metadataKey = newMetadataKey;
                                    self.metadataValue = newMetadataValue;
                                    removeMetadataEnabled = YES;
                                    [self.tableView reloadData];
                                    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
                                    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                                        [self.folderViewController refreshButtonPressed:nil];
                                    }
                                    else {
                                        self.folderViewController.needsRefreshing = YES;
                                    }
                                    [[NSNotificationCenter defaultCenter] removeObserver:addFolderSuccessObserver];
                                }];
    
    addFolderFailureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object 
                                                                                  queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
                                {         
                                    [object.metadata removeObjectForKey:newMetadataKey];
                                    [object.metadata setObject:metadataValue forKey:metadataKey];
                                    [activityIndicatorView removeFromSuperviewAndRelease];
                                    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
                                    [self.tableView reloadData];
                                    [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
                                    
                                    [[NSNotificationCenter defaultCenter] removeObserver:addFolderFailureObserver];
                                }];
    

}

@end
