//
// BusSearchBoxViewController.m
// GoToBus
//
// Created by haibara on 12/3/14.
//
//

#import "BusSearchBoxViewController.h"
#import "AppTracker.h"
#import "Lang.h"
#import "SDK.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "ImageUtils.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "CalendarViewController.h"
#import "ComboBoxViewController.h"
#import <BlocksKit/BlocksKit.h>
#import <BlocksKit/BlocksKit+UIKit.h>
#import <BlocksKit/A2DynamicDelegate.h>
#import <libextobjc/EXTScope.h>
#import <PureLayout/PureLayout.h>
#import "Utility.h"
#import "PerlWS.h"
#import "CustomDualLeftRightCell.h"
#import "CustomDualStepperCell.h"
#import "CustomDualSubtitleCell.h"
#import "ProductSearchListVC.h"
#import "CheckInActionHandler.h"
#import "TrackBusStatusViewController.h"
#import "SelfCheckInSearchViewController.h"
#import "Vars.h"
#import "RangeCalendarViewController.h"
#import "CalendarPrice.h"
#import <YYModel/YYModel.h>
#import <PINCache/PINCache.h>
@interface BusSearchBoxParam ()
@end

@implementation BusSearchBoxParam

- (instancetype)init {
	self = [super init];
	if (self) {
		self.roundtrip = YES;
		self.adult_num = 1;
		self.child_num = 0;
		self.filter_date = [[DateFormatUtils ISO_DATE_FORMAT] format:[NSDate date]];
		self.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:[DateUtils addDays:[NSDate date] amount:1]];
	}
	return self;
}

@end

@interface BusSearchBoxViewController ()
@property (nonatomic, strong) BusSearchBoxParam *busSearchParam;
@property (nonatomic, strong) NSMutableArray *cellDataArray;
@property (nonatomic, strong) CalendarPrice *calendarPrice;
@property(nonatomic, strong) UISegmentedControl *segmentedControl;
@end

@implementation BusSearchBoxViewController

- (instancetype)init {
	if ((self = [super init])) {
		self.title = @"Find Bus Tickets";
		[[Vars appDelegate] applyDefaultConfigurationForViewController:self];
	}
	return self;
}

- (void)viewDidLoad {
	[super viewDidLoad];
	
	[[AppTracker sharedInstance] sendView:[self class]];

//	[[Vars appDelegate].shopCarts empty];

	self.busSearchParam = [[BusSearchBoxParam alloc] init];

	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([CustomDualSubtitleCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([CustomDualSubtitleCell class])];
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([CustomDualLeftRightCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([CustomDualLeftRightCell class])];
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([CustomDualStepperCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([CustomDualStepperCell class])];
	if (YES) {
		UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), [UIConstants defaultSegmentedControlHeight] + 15 * 2)];
		UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Round trip", @"One way"]];
		segmentedControl.frame = CGRectMake(15, 15, CGRectGetWidth([UIScreen mainScreen].bounds) - 15 * 2, [UIConstants defaultSegmentedControlHeight]);
		segmentedControl.selectedSegmentIndex = 0;
		[segmentedControl addTarget:self action:@selector(changedRT:) forControlEvents:UIControlEventValueChanged];
		self.segmentedControl = segmentedControl;
		[headerView addSubview:segmentedControl];
		self.tableView.tableHeaderView = headerView;
	}
	if (YES) {
		UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), [UIConstants defaultTableViewRowHeight] * 2 + 15 * 2 + 20)];
		UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
		button.frame = CGRectMake(15, 15, CGRectGetWidth([UIScreen mainScreen].bounds) - 15 * 2, [UIConstants defaultTableViewRowHeight]);
		button.backgroundColor = [Vars defaultTintColor];
		button.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont buttonFontSize]];
		[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		[button setTitle:@"Find Bus Tickets" forState:UIControlStateNormal];
		[button addTarget:self action:@selector(submitForm) forControlEvents:UIControlEventTouchUpInside];
		[Utility addRoundedBorderToButton:button];
		[footerView addSubview:button];
		
		UIButton *checkBusStatusButton = [UIButton buttonWithType:UIButtonTypeCustom];
		checkBusStatusButton.frame = CGRectMake(0, CGRectGetHeight(button.frame) + 35, CGRectGetWidth([UIScreen mainScreen].bounds) / 2.0, [UIConstants defaultTableViewRowHeight]);
		[checkBusStatusButton setImage:[ImageUtils imageNamed:@"track_bus" tintColor:[Vars defaultTintColor]] forState:UIControlStateNormal];
		[checkBusStatusButton setTitle:@"Track Bus Status" forState:UIControlStateNormal];
		checkBusStatusButton.titleLabel.font = [UIFont systemFontOfSize:15];
		[checkBusStatusButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 8, 0, 0)];
		[checkBusStatusButton addTarget:self action:@selector(checkBusStatus) forControlEvents:UIControlEventTouchUpInside];
		[checkBusStatusButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
		[footerView addSubview:checkBusStatusButton];
		
		UIButton *selfCheckInButton = [UIButton buttonWithType:UIButtonTypeCustom];
		selfCheckInButton.frame = CGRectMake(CGRectGetWidth(checkBusStatusButton.frame), CGRectGetHeight(button.frame) + 35, CGRectGetWidth(checkBusStatusButton.frame), [UIConstants defaultTableViewRowHeight]);
		[selfCheckInButton setImage:[ImageUtils adjustImage:[ImageUtils scaleImage:[SelfCheckInSearchViewController imageForSelfCheckInIcon] toWidth:24] tintColor:[Vars defaultTintColor]] forState:UIControlStateNormal];
		[selfCheckInButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
		[selfCheckInButton setTitle:@"Self Check-in" forState:UIControlStateNormal];
		selfCheckInButton.titleLabel.font =[UIFont systemFontOfSize:15];
		[selfCheckInButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 8, 0, 0)];
		[selfCheckInButton addTarget:self action:@selector(checkIn) forControlEvents:UIControlEventTouchUpInside];
		[footerView addSubview:selfCheckInButton];
		
		self.tableView.tableFooterView = footerView;
	}
	[self buildCellDataSource];
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	// ajax
	[[Vars appDelegate] getSearchDataSource:@"Bus"];
}

#pragma mark - NetWork

-(void)getCalendarPrice{
	//	https://search.gotobus.com/search/get-lowest-price-json.do?fromCity=New York, NY&toCity=Washington, DC
	NSString *urlString = [[Vars javaSearchEndpoint] stringByAppendingString:@"/get-lowest-price-json.do"];
	
	NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
	if ([Vars clientDomainId] == VendorIdCoachRun || [Vars clientDomainId] == VendorIdEastWestBus) {
		[parameters setValue:@([Vars clientDomainId]) forKey:@"vendorId"];
	}
	
	[parameters setValue:self.busSearchParam.bus_from forKey:@"fromCity"];
	[parameters setValue:self.busSearchParam.bus_to forKey:@"toCity"];
	
	NSMutableDictionary *calendarKey = parameters;
	NSString *dateString = [[DateFormatUtils ISO_DATE_FORMAT] format: [NSDate date]];
	[calendarKey setValue:dateString forKey:@"date"];
	id jsonObject = [[Vars appDelegate].coreData getCalendarPriceWithKey:calendarKey.description];
	if (jsonObject) {
		self.calendarPrice = [CalendarPrice yy_modelWithJSON:jsonObject];
		return;
	}
	[Utility getJSONFromRequestWithMethod:@"GET" url:urlString parameters:parameters success:^(id jsonObject) {
		self.calendarPrice = [CalendarPrice yy_modelWithJSON:jsonObject];
		[[Vars appDelegate].coreData setCalendarPrice:jsonObject withKey:calendarKey.description];
	}];
	
}

#pragma mark - Action

- (void)changedRT:(UISegmentedControl *)segmentedControl {
	if (segmentedControl.selectedSegmentIndex == 0) {
		self.busSearchParam.roundtrip = YES;
		if ([StringUtils isEmpty:self.busSearchParam.return_date]) {
			self.busSearchParam.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:[DateUtils addDays:[[DateFormatUtils ISO_DATE_FORMAT] parse:self.busSearchParam.filter_date] amount:2]];
		}
	} else if (segmentedControl.selectedSegmentIndex == 1) {
		self.busSearchParam.roundtrip = NO;
		self.busSearchParam.return_date = nil;
	}
	[self configureTableViewCellDataForRoundtrip];
	[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

- (void)changeToFrom {
	if ([StringUtils isEmpty:self.busSearchParam.bus_from] || [StringUtils isEmpty:self.busSearchParam.bus_to]) {
		return;
	}
	NSArray *tmpArray = [Vars appDelegate].coreData.busDepartureArrivalPairs[self.busSearchParam.bus_to];
	BOOL isExist = [tmpArray containsObject:self.busSearchParam.bus_from];
	NSString *tmpString = self.busSearchParam.bus_from;
	self.busSearchParam.bus_from = self.busSearchParam.bus_to;
	if (isExist) {
		self.busSearchParam.bus_to = tmpString;
	} else {
		self.busSearchParam.bus_to = nil;
	}
	[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}

- (void)submitForm {
	NSString *message = nil;
	if (self.busSearchParam.roundtrip) {
		if ([StringUtils isEmpty:self.busSearchParam.filter_date] || [StringUtils isEmpty:self.busSearchParam.return_date]) {
			message = @"Departure and return dates must be specified";
		}
	} else {
		if ([StringUtils isEmpty:self.busSearchParam.filter_date]) {
			message = @"Departure date must be specified";
		}
	}
	if ([StringUtils isEmpty:self.busSearchParam.bus_from] || [StringUtils isEmpty:self.busSearchParam.bus_to]) {
		message = @"Departure and arrival locations must be specified";
	}
	if (!message) {
		[Vars appDelegate].shopCarts.adultNum = self.busSearchParam.adult_num;
		[Vars appDelegate].shopCarts.childNum = self.busSearchParam.child_num;
		NSArray *unshiftArray = [CocoaUtils unshiftObject:self.busSearchParam.bus_from toArray:[CocoaUtils mutableArray:[CocoaUtils objectFromUserDefaultsForKey:UserDefaultsKeyHistoryBusSearchDepartureList]] count:10];
		[CocoaUtils synchronizeUserDefaultsBySettingWithObject:unshiftArray forKey:UserDefaultsKeyHistoryBusSearchDepartureList];
		ProductSearchListVC *viewController = [[ProductSearchListVC alloc] init];
		viewController.roundtrip = self.busSearchParam.roundtrip;
		viewController.currentDepartString = self.busSearchParam.filter_date;
		viewController.currentReturnString = self.busSearchParam.return_date;
		viewController.returnCity = self.busSearchParam.bus_to;
		viewController.departCity = self.busSearchParam.bus_from;
		[self.navigationController pushViewController:viewController animated:YES];
	} else {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:message];
	}
}

-(void)checkBusStatus{
	    [self performSegueWithViewControllerClass:[TrackBusStatusViewController class]];
}

- (void)checkIn {
    [self performSegueWithViewControllerClass:[SelfCheckInSearchViewController class]];
}

#pragma mark - Segue
- (void)performSegueWithViewControllerClass:(Class)class {
	UIViewController *viewController = [[class alloc] init];
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForDepartureCityOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	NSArray *departures = [Vars appDelegate].coreData.busDepartureArrivalPairs.allKeys;
	ComboBoxViewController *viewController = [[ComboBoxViewController alloc] init];
	viewController.title = @"Departure City";
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.suggestionTitle = @"Popular";
	viewController.historyTitle = IMLocalizedString(@"Recent Search");
	[viewController setItemsWithArray:[Vars appDelegate].coreData.busDepartureArrivalPairs.allKeys];
	[viewController suggestValues:[Vars appDelegate].coreData.busSearchDataSource[@"hot_departures"]];
	[viewController setHistoryValues:[CocoaUtils objectFromUserDefaultsForKey:UserDefaultsKeyHistoryBusSearchDepartureList]];
	[viewController setDidSelectItemBlock:^(ComboBoxItem *item) {
		[self.navigationController popViewControllerAnimated:YES];
		self.busSearchParam.bus_from = item.value;
		if ([[Vars appDelegate].coreData.busDepartureArrivalPairs[self.busSearchParam.bus_from] count] == 1) {
			self.busSearchParam.bus_to = [[Vars appDelegate].coreData.busDepartureArrivalPairs[self.busSearchParam.bus_from] firstObject];
		} else {
			self.busSearchParam.bus_to = nil;
		}
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
	}];
	[viewController setHistoryChangedBlock:^(NSArray < ComboBoxItem * > *items) {
		[CocoaUtils synchronizeUserDefaultsBySettingWithObject:[items valueForKeyPath:@"value"] forKey:UserDefaultsKeyHistoryBusSearchDepartureList];
	}];
	viewController.allowsLocation = YES;
	[viewController setGeocodeBlock:^(ComboBoxViewController *viewController) {
		[Utility requestLocationWithCompletion:^(BOOL granted, CLLocation *location, NSError *error) {
			if (!granted || !location) {
				[viewController updatePlacemark:nil];
			} else {
				[Utility reverseGeocodeLocation:location completionHandler:^(CLPlacemark *placemark, NSError *error) {
					[viewController updatePlacemark:placemark];
				}];
			}
		}];
	}];
	[viewController setPlacemarkFormattingBlock:^NSString *(CLPlacemark *placemark) {
		return placemark.locality;
	}];
	[viewController setPlacemarkTransformationBlock:^id (CLPlacemark *placemark) {
		return [Destination localityTransformation:[NSDictionary dictionaryWithObjects:departures forKeys:departures] objectForPlacemark:placemark];
	}];
	if (![StringUtils isEmpty:self.busSearchParam.bus_from]) {
		[viewController selectValue:self.busSearchParam.bus_from];
	}
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForArrivalCityOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	if ([StringUtils isEmpty:self.busSearchParam.bus_from]) {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:[NSString stringWithFormat:@"Please select %@ first", @"Departure City".lowercaseString]];
		return;
	}
	ComboBoxViewController *viewController = [[ComboBoxViewController alloc] init];
	viewController.title = @"Arrival City";
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	[viewController setItemsWithArray:[Vars appDelegate].coreData.busDepartureArrivalPairs[self.busSearchParam.bus_from]];
	[viewController setDidSelectItemBlock:^(ComboBoxItem *item) {
		[self.navigationController popViewControllerAnimated:YES];
		self.busSearchParam.bus_to = item.value;
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
		[self getCalendarPrice];
	}];
	if (![StringUtils isEmpty:self.busSearchParam.bus_to]) {
		[viewController selectValue:self.busSearchParam.bus_to];
	}
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForDepartureDateOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	RangeCalendarViewController *viewController = [[RangeCalendarViewController alloc] init];
	viewController.title = IMLocalizedString(@"Departure Date");
	viewController.isRoundTrip = self.busSearchParam.roundtrip;
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.minimumDate = [NSDate date];
	viewController.maximumDate = [DateUtils addMonths:[NSDate date] amount:6];
	viewController.calendarPrice = self.calendarPrice;
	viewController.isHeaderViewUserInteractionEnabled = YES;
	viewController.hidesBottomBarWhenPushed = YES;
	if (self.calendarPrice) {
		viewController.isShowPriceTitle = YES;
	}
	[viewController setDidCancelBlock:^{
		[self.navigationController popViewControllerAnimated:YES];
	}];
	[viewController setDidDoneRangeBlock:^(NSDate *startDate, NSDate *endDate) {
		if (!startDate || !endDate) {
			[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:@"Please select departure date and return date"];
			return;
		}
		self.segmentedControl.selectedSegmentIndex = 0;
		[self changedRT:self.segmentedControl];
		[self.navigationController popViewControllerAnimated:YES];
		self.busSearchParam.filter_date = [[DateFormatUtils ISO_DATE_FORMAT] format:startDate];
		self.busSearchParam.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:endDate];
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
	}];
	[viewController setDidDoneBlock:^(NSDate *date) {
		[self.navigationController popViewControllerAnimated:YES];
		self.segmentedControl.selectedSegmentIndex = 1;
		[self changedRT:self.segmentedControl];
		NSDate *departureDate = date;
		self.busSearchParam.filter_date = [[DateFormatUtils ISO_DATE_FORMAT] format:departureDate];
		if ([StringUtils isEmpty:self.busSearchParam.return_date] || [self.busSearchParam.filter_date compare:self.busSearchParam.return_date] == NSOrderedDescending) {
			NSDate *returnDate = [DateUtils addDays:departureDate amount:1];
			if ([DateUtils truncated:returnDate compareTo:viewController.maximumDate  unit:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay] == NSOrderedDescending) {
				returnDate = viewController.maximumDate ;
			}
			self.busSearchParam.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:returnDate];
		}
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
	}];
	if (![StringUtils isEmpty:self.busSearchParam.filter_date]) {
			[viewController selectDate:[[DateFormatUtils ISO_DATE_FORMAT] parse:self.busSearchParam.filter_date]];
		}
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForDateRangeOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	if (!self.busSearchParam.roundtrip) {
		return;
	}
	RangeCalendarViewController *viewController = [[RangeCalendarViewController alloc] init];
	viewController.title = @"Departure & Return";
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.isRoundTrip = self.busSearchParam.roundtrip;
	viewController.isHeaderViewUserInteractionEnabled = YES;
	viewController.minimumDate = [NSDate date];
	viewController.maximumDate = [DateUtils addMonths:[NSDate date] amount:6];
	viewController.calendarPrice = self.calendarPrice;
	viewController.hidesBottomBarWhenPushed = YES;
	if (self.calendarPrice) {
		viewController.isShowPriceTitle = YES;
	}
	[viewController setDidCancelBlock:^{
		[self.navigationController popViewControllerAnimated:YES];
	}];
	[viewController setDidDoneBlock:^(NSDate *date) {
		[self.navigationController popViewControllerAnimated:YES];
		self.segmentedControl.selectedSegmentIndex = 1;
		[self changedRT:self.segmentedControl];
		NSDate *departureDate = date;
		self.busSearchParam.filter_date = [[DateFormatUtils ISO_DATE_FORMAT] format:departureDate];
		if ([StringUtils isEmpty:self.busSearchParam.return_date] || [self.busSearchParam.filter_date compare:self.busSearchParam.return_date] == NSOrderedDescending) {
			NSDate *returnDate = [DateUtils addDays:departureDate amount:1];
			if ([DateUtils truncated:returnDate compareTo:viewController.maximumDate  unit:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay] == NSOrderedDescending) {
				returnDate = viewController.maximumDate ;
			}
			self.busSearchParam.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:returnDate];
		}
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

	}];
	[viewController setDidDoneRangeBlock:^(NSDate *startDate, NSDate *endDate) {
		if (!startDate || !endDate) {
			[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:@"Please select departure date and return date"];
			return;
		}
		[self.navigationController popViewControllerAnimated:YES];
		self.busSearchParam.filter_date = [[DateFormatUtils ISO_DATE_FORMAT] format:startDate];
		self.busSearchParam.return_date = [[DateFormatUtils ISO_DATE_FORMAT] format:endDate];
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
	}];
	if (![StringUtils isEmpty:self.busSearchParam.filter_date] && ![StringUtils isEmpty:self.busSearchParam.return_date]) {
		[viewController selectRangeFromStartDate:[[DateFormatUtils ISO_DATE_FORMAT] parse:self.busSearchParam.filter_date] toEndDate:[[DateFormatUtils ISO_DATE_FORMAT] parse:self.busSearchParam.return_date]];
	}
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Property

#pragma mark - Private

- (void)buildCellDataSource {
	NSMutableArray *array = [NSMutableArray array];
	self.cellDataArray = array;
	if (YES) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.reuseIdentifier = NSStringFromClass([CustomDualSubtitleCell class]);
		data.usesAutomaticDimension = YES;
		array[0] = data;
	}
	[self configureTableViewCellDataForRoundtrip];
	if (YES) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.reuseIdentifier = NSStringFromClass([CustomDualStepperCell class]);
		[data setNeedLayoutFittingHeight];
		array[2] = data;
	}
}

- (void)configureTableViewCellDataForRoundtrip {
	NSMutableArray *array = self.cellDataArray;
	@weakify(self)
	TableViewCellData *data = [[TableViewCellData alloc] init];
	if (self.busSearchParam.roundtrip) {
		data.reuseIdentifier = NSStringFromClass([CustomDualLeftRightCell class]);
		data.reuseHeight = [UIConstants defaultTableViewRowHeight] + 5 * 2;
		[data setNeedLayoutFittingHeight];
	} else {
		data.reuseHeight = [UIConstants defaultTableViewRowHeight] + 5 * 2;
		data.style = UITableViewCellStyleSubtitle;
		data.image = [DrawUtils tableViewCellImageWithFAKIcon:[FAKFontAwesome calendarIconWithSize:24] fillColor:[UIColor lightGrayColor]];
		data.text = IMLocalizedString(@"Departure Date");
		data.textFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		[data setDetailTextBlock:^NSString *{
			@strongify(self)
			return [Utility localizedStringWithStandardDateString:self.busSearchParam.filter_date];
		}];
		data.detailTextColor = [Vars defaultTintColor];
		data.detailTextFont = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
		data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
		[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
			@strongify(self)
			[self performSegueForDepartureDateOnTableView: tableView atIndexPath: indexPath];
		}];
	}
	array[1] = data;
}

#pragma mark - Table view methods

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	return self.cellDataArray.count;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualSubtitleCell class])]) {
		return [UIToolkit instantiateRowHeightForTableViewCellWithNibName:NSStringFromClass([CustomDualSubtitleCell class])];
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualLeftRightCell class])]) {
		return [UIToolkit instantiateRowHeightForTableViewCellWithNibName:NSStringFromClass([CustomDualLeftRightCell class])];
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualStepperCell class])]) {
		return [UIToolkit instantiateRowHeightForTableViewCellWithNibName:NSStringFromClass([CustomDualStepperCell class])];
	}
	return [UIConstants defaultTableViewRowHeight];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	return [UIToolkit tableView:tableView atIndexPath:indexPath rowHeightWithData:data];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	@weakify(self)
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualSubtitleCell class])]) {
		CustomDualSubtitleCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomDualSubtitleCell class])];
		[CocoaUtils removeGestureRecognizerKindOfClass:[UITapGestureRecognizer class] fromView:cell.imageView];
		[cell.topSelectionButton bk_removeEventHandlersForControlEvents:UIControlEventTouchUpInside];
		[cell.bottomSelectionButton bk_removeEventHandlersForControlEvents:UIControlEventTouchUpInside];
		cell.imageView.userInteractionEnabled = YES;
		[cell.imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeToFrom)]];
		cell.imageView.image = [ImageUtils rotateImage:[DrawUtils tableViewCellImageWithFAKIcon:[FAKFontAwesome exchangeIconWithSize:24] fillColor:[Vars defaultTintColor]] byDegrees:-90];
		cell.topTitleLabel.text = @"Leaving from";
		cell.topTitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.topSubtitleLabel.text = ![StringUtils isEmpty:self.busSearchParam.bus_from] ? self.busSearchParam.bus_from : @"Departure City";
		cell.topSubtitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.topSubtitleLabel.textColor = ![StringUtils isEmpty:self.busSearchParam.bus_from] ? [Vars defaultTintColor] : [UIColor lightGrayColor];
		cell.bottomTitleLabel.text = @"Going to";
		cell.bottomTitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.bottomSubtitleLabel.text = ![StringUtils isEmpty:self.busSearchParam.bus_to] ? self.busSearchParam.bus_to : @"Arrival City";
		cell.bottomSubtitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.bottomSubtitleLabel.textColor = ![StringUtils isEmpty:self.busSearchParam.bus_to] ? [Vars defaultTintColor] : [UIColor lightGrayColor];
		[cell.topSelectionButton bk_addEventHandler:^(id sender) {
			@strongify(self)
			[self performSegueForDepartureCityOnTableView: tableView atIndexPath:indexPath];
		} forControlEvents:UIControlEventTouchUpInside];
		[cell.bottomSelectionButton bk_addEventHandler:^(id sender) {
			@strongify(self)
			[self performSegueForArrivalCityOnTableView: tableView atIndexPath:indexPath];
		} forControlEvents:UIControlEventTouchUpInside];
		cell.topRightView = [DrawUtils tableViewCellAccessoryDisclosureIndicatorRightWithColor:[Vars defaultTintColor]];
		cell.bottomRightView = [DrawUtils tableViewCellAccessoryDisclosureIndicatorRightWithColor:[Vars defaultTintColor]];
		return cell;
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualLeftRightCell class])]) {
		CustomDualLeftRightCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomDualLeftRightCell class])];
		[cell.leftSelectionButton bk_removeEventHandlersForControlEvents:UIControlEventTouchUpInside];
		[cell.rightSelectionButton bk_removeEventHandlersForControlEvents:UIControlEventTouchUpInside];
		cell.imageView.image = [DrawUtils tableViewCellImageWithFAKIcon:[FAKFontAwesome calendarIconWithSize:24] fillColor:[UIColor lightGrayColor]];
		cell.leftTitleLabel.text = IMLocalizedString(@"Departure Date");
		cell.leftTitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.leftSubtitleLabel.text = [Utility localizedStringWithStandardDateString:self.busSearchParam.filter_date];
		cell.leftSubtitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.leftSubtitleLabel.textColor = [Vars defaultTintColor];
		cell.rightTitleLabel.text = @"Return Date";
		cell.rightTitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.rightSubtitleLabel.text = [Utility localizedStringWithStandardDateString:self.busSearchParam.return_date];
		cell.rightSubtitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
		cell.rightSubtitleLabel.textColor = [Vars defaultTintColor];
		[cell.leftSelectionButton bk_addEventHandler:^(id sender) {
			@strongify(self)
			[self performSegueForDateRangeOnTableView: tableView atIndexPath:indexPath];
		} forControlEvents:UIControlEventTouchUpInside];
		[cell.rightSelectionButton bk_addEventHandler:^(id sender) {
			@strongify(self)
			[self performSegueForDateRangeOnTableView: tableView atIndexPath:indexPath];
		} forControlEvents:UIControlEventTouchUpInside];
		return cell;
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([CustomDualStepperCell class])]) {
		CustomDualStepperCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomDualStepperCell class])];
		cell.imageView.image = [DrawUtils tableViewCellImageWithFAKIcon:[FAKFontAwesome userIconWithSize:28] fillColor:[UIColor lightGrayColor]];
		cell.titleLabel.text = @"Passengers";
		cell.topTextLabel.text = @"Adult";
		cell.topTextLabel.textColor = [Vars defaultTintColor];
		cell.bottomTextLabel.text = @"Child";
		cell.bottomTextLabel.textColor = [Vars defaultTintColor];
		cell.topDetailStepper.minimumValue = 1;
		cell.topDetailStepper.maximumValue = 50;
		cell.topDetailStepper.value = self.busSearchParam.adult_num;
		cell.bottomDetailStepper.minimumValue = 0;
		cell.bottomDetailStepper.maximumValue = 50;
		cell.bottomDetailStepper.value = self.busSearchParam.child_num;
		cell.topDetailStepper.style = StepperStyletextField;
		cell.bottomDetailStepper.style = StepperStyletextField;
		[cell.topDetailStepper editValueChangeBlock:^(IMStepper *stepper) {
			self.busSearchParam.adult_num = stepper.value;
		}];
		[cell.bottomDetailStepper editValueChangeBlock:^(IMStepper *stepper) {
			self.busSearchParam.child_num = stepper.value;
		}];
		[cell.topDetailStepper setValueChangedBlock:^(IMStepper *stepper) {
			@strongify(self)
			self.busSearchParam.adult_num = stepper.value;
		}];
		[cell.bottomDetailStepper setValueChangedBlock:^(IMStepper *stepper) {
			@strongify(self)
			self.busSearchParam.child_num = stepper.value;
		}];
		return cell;
	}
	return [UIToolkit tableView:tableView atIndexPath:indexPath cellWithData:data];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	[UIToolkit tableView:tableView atIndexPath:indexPath didSelectWithData:data];
}

@end

