//
//  CreateRoomRequest.m
//  SFS2X
//
//  Original development by Infosfer Game Technologies Ltd. | http://www.infosfer.com.
//
//  Maintained and developed by A51 Integrated.
//  Copyright 2012 A51 Integrated | http://a51integrated.com. All rights reserved.
//

#import "CreateRoomRequest.h"
#import "SFSArray.h"
#import "RoomVariable.h"
#import "Variable.h"
#import "RoomSettings.h"
#import "RoomExtension.h"
#import "MMORoomSettings.h"

NSString * const CreateRoomRequest_KEY_ROOM = @"r";
NSString * const CreateRoomRequest_KEY_NAME = @"n";
NSString * const CreateRoomRequest_KEY_PASSWORD = @"p";
NSString * const CreateRoomRequest_KEY_GROUP_ID = @"g";
NSString * const CreateRoomRequest_KEY_ISGAME = @"ig";
NSString * const CreateRoomRequest_KEY_MAXUSERS = @"mu";
NSString * const CreateRoomRequest_KEY_MAXSPECTATORS = @"ms";
NSString * const CreateRoomRequest_KEY_MAXVARS = @"mv";
NSString * const CreateRoomRequest_KEY_ROOMVARS = @"rv";
NSString * const CreateRoomRequest_KEY_PERMISSIONS = @"pm";
NSString * const CreateRoomRequest_KEY_EVENTS = @"ev";
NSString * const CreateRoomRequest_KEY_EXTID = @"xn";
NSString * const CreateRoomRequest_KEY_EXTCLASS = @"xc";
NSString * const CreateRoomRequest_KEY_EXTPROP = @"xp";
NSString * const CreateRoomRequest_KEY_AUTOJOIN = @"aj";
NSString * const CreateRoomRequest_KEY_ROOM_TO_LEAVE = @"rl";

//--- MMO Keys -------------------------------------------------------------------
NSString * const CreateRoomRequest_KEY_MMO_DEFAULT_AOI = @"maoi";
NSString * const CreateRoomRequest_KEY_MMO_MAP_LOW_LIMIT = @"mllm";
NSString * const CreateRoomRequest_KEY_MMO_MAP_HIGH_LIMIT = @"mlhm";
NSString * const CreateRoomRequest_KEY_MMO_USER_MAX_LIMBO_SECONDS = @"muls";
NSString * const CreateRoomRequest_KEY_MMO_PROXIMITY_UPDATE_MILLIS = @"mpum";
NSString * const CreateRoomRequest_KEY_MMO_SEND_ENTRY_POINT = @"msep";
NSString * const CreateRoomRequest_KEY_ALLOW_JOIN_INVITATION_BY_OWNER = @"aji";


@implementation CreateRoomRequest


-(id)initWithRoomSettings:(RoomSettings *)settings autoJoin:(BOOL)autoJoin roomToLeave:(id<Room>)roomToLeave {
	if ((self = [super initWithId:BaseRequest_CreateRoom])) {
		_settings = settings;
		_autoJoin = autoJoin;
		_roomToLeave = roomToLeave;
	}
	
	return self;
}

+(id)requestWithRoomSettings:(RoomSettings *)settings autoJoin:(BOOL)autoJoin roomToLeave:(id<Room>)roomToLeave {
	CreateRoomRequest *req = [[CreateRoomRequest alloc] initWithRoomSettings:settings autoJoin:autoJoin roomToLeave:roomToLeave];
	return req;
}

+(id)requestWithRoomSettings:(RoomSettings *)settings {
	CreateRoomRequest *req = [[CreateRoomRequest alloc] initWithRoomSettings:settings autoJoin:NO roomToLeave:nil];
	return req;
}

-(void)validate:(SmartFox2XClient *)sfs {
	
	NSMutableArray *errors = [NSMutableArray array];
	
	if (_settings.name == nil || [_settings.name length] == 0) {
		[errors addObject:@"Missing room name"];
	}
	
	if (_settings.maxUsers <= 0) {
		[errors addObject:@"maxUsers must be > 0"];
	}
	
	if (_settings.extension != nil) {
		if (_settings.extension.className == nil || [_settings.extension.className length] == 0) {
			[errors addObject:@"Missing Extension class name"];
		}
		
		if (_settings.extension.id_ == nil || [_settings.extension.id_ length] == 0) {
			[errors addObject:@"Missing Extension id"];
		}
	}
    
    
    if ([_settings isKindOfClass:[MMORoomSettings class]])
    {
        MMORoomSettings* mmoSettings = (MMORoomSettings*) _settings;
        
        if (mmoSettings.defaultAOI == nil)
            [errors addObject:@"Missing default AOI (area of interest)"];

        
        if (mmoSettings.mapLimits != nil && (mmoSettings.mapLimits.lowerLimit == nil || mmoSettings.mapLimits.higherLimit == nil))
            [errors addObject:@"Map limits must be both defined"];
    }
		
	if ([errors count] > 0) {
		@throw [SFSValidationException validationExceptionWithReason:@"CreateRoom request error" errors:errors];
	}
	
}


-(void)execute:(SmartFox2XClient *)sfs
{
	
	[_sfso putUtfString:CreateRoomRequest_KEY_NAME value:_settings.name];
	[_sfso putUtfString:CreateRoomRequest_KEY_GROUP_ID value:_settings.groupId];
	[_sfso putUtfString:CreateRoomRequest_KEY_PASSWORD value:_settings.password];
	[_sfso putBool:CreateRoomRequest_KEY_ISGAME value:_settings.isGame];
	[_sfso putShort:CreateRoomRequest_KEY_MAXUSERS value:_settings.maxUsers];
	[_sfso putShort:CreateRoomRequest_KEY_MAXSPECTATORS value:_settings.maxSpectators];
	[_sfso putShort:CreateRoomRequest_KEY_MAXVARS value:_settings.maxVariables];
    [_sfso putBool:CreateRoomRequest_KEY_ALLOW_JOIN_INVITATION_BY_OWNER value:_settings.allowOwnerOnlyInvitation];
	
	// Handle Room Variables
	if (_settings.variables != nil && [_settings.variables count] > 0)
    {
		id<ISFSArray> roomVars = [SFSArray newInstance];
		
		for (id item in _settings.variables)
        {
			if ([item conformsToProtocol:@protocol(RoomVariable)])
            {
				id<RoomVariable> rVar = (id<RoomVariable>) item;
				[roomVars addSFSArray:[rVar toSFSArray]];
			}
		}
		
		[_sfso putSFSArray:CreateRoomRequest_KEY_ROOMVARS value:roomVars];
	}
	
	
	// Handle Permissions
	
	if(_settings.permissions != nil){
		NSMutableArray *sfsPermissions = [NSMutableArray array];
		
		[sfsPermissions addObject:[NSNumber numberWithBool:_settings.permissions.allowNameChange]];
		[sfsPermissions addObject:[NSNumber numberWithBool:_settings.permissions.allowPasswordStateChange]];
		[sfsPermissions addObject:[NSNumber numberWithBool:_settings.permissions.allowPublicMessages]];
		[sfsPermissions addObject:[NSNumber numberWithBool:_settings.permissions.allowResizing]];
		
		[_sfso putBoolArray:CreateRoomRequest_KEY_PERMISSIONS value:sfsPermissions];
		
	}
	
	// Handle Events
	
	if(_settings.events != nil) {
		NSMutableArray *sfsEvents = [NSMutableArray array];
		
		[sfsEvents addObject:[NSNumber numberWithBool:_settings.events.allowUserEnter]];
		[sfsEvents addObject:[NSNumber numberWithBool:_settings.events.allowUserExit]];
		[sfsEvents addObject:[NSNumber numberWithBool:_settings.events.allowUserCountChange]];
		[sfsEvents addObject:[NSNumber numberWithBool:_settings.events.allowUserVariablesUpdate]];
		
		[_sfso putBoolArray:CreateRoomRequest_KEY_EVENTS value:sfsEvents];
	}
	
	// Handle Extension data
	
	if(_settings.extension != nil) {
		[_sfso putUtfString:CreateRoomRequest_KEY_EXTID value:_settings.extension.id_];
		[_sfso putUtfString:CreateRoomRequest_KEY_EXTCLASS value:_settings.extension.className];
		
		// Send the properties file only if was specified
		
		if (_settings.extension.propertiesFile != nil && [_settings.extension.propertiesFile length] > 0) {
			[_sfso putUtfString:CreateRoomRequest_KEY_EXTPROP value:_settings.extension.propertiesFile];
		}
	}
    
    //--- MMORooms ------------------------------------------------------------------------
    if ([_settings isKindOfClass:[MMORoomSettings class]])
    {
        MMORoomSettings* mmoSettings = (MMORoomSettings*) _settings;
        BOOL useFloats = mmoSettings.defaultAOI.isFloat;
        
        if (useFloats)
        {
            [_sfso putFloatArray:CreateRoomRequest_KEY_MMO_DEFAULT_AOI value:[mmoSettings.defaultAOI toArray]];
            
            if (mmoSettings.mapLimits != nil)
            {
                [_sfso putFloatArray:CreateRoomRequest_KEY_MMO_MAP_LOW_LIMIT
                               value:[mmoSettings.mapLimits.lowerLimit toArray]];
                
                [_sfso putFloatArray:CreateRoomRequest_KEY_MMO_MAP_HIGH_LIMIT
                               value:[mmoSettings.mapLimits.higherLimit toArray]];
                
            }
            
            else
            {
                [_sfso putIntArray:CreateRoomRequest_KEY_MMO_MAP_LOW_LIMIT
                               value:[mmoSettings.mapLimits.lowerLimit toArray]];
                
                [_sfso putIntArray:CreateRoomRequest_KEY_MMO_MAP_HIGH_LIMIT
                               value:[mmoSettings.mapLimits.higherLimit toArray]];
            }
            
            [_sfso putShort:CreateRoomRequest_KEY_MMO_USER_MAX_LIMBO_SECONDS
                      value:mmoSettings.userMaxLimboSeconds];
        
            [_sfso putShort:CreateRoomRequest_KEY_MMO_PROXIMITY_UPDATE_MILLIS
                      value:mmoSettings.proximityListUpdateMillis];
        
            [_sfso putBool:CreateRoomRequest_KEY_MMO_SEND_ENTRY_POINT
                     value:mmoSettings.sendAOIEntryPoint];
        }
    }
    
	
	// AutoJoin
	
	[_sfso putBool:CreateRoomRequest_KEY_AUTOJOIN value:_autoJoin];
	
	// Room to leave
	
	if (_roomToLeave != nil) {
		[_sfso putInt:CreateRoomRequest_KEY_ROOM_TO_LEAVE value:[_roomToLeave id]];
	}
}




@end
