/* instance of flowPage */
var flowPage   = null;

var langErrors = null;

var langMain = null;
/**
 * 
 */
function Flow(integrationMode){
	
	//private properties
	/** instance of current customer **/
	var _customer        = null;
	/** instance of selected asset **/
	var _selectedAsset   = null;
	/** instance of selected option **/
	var _selectedOption  = null;
	/** array of options objects that related to selected asset **/
	var _options = null;
	/** template object of new position */
	var _newPosition = null;
	
	var _openPositions = [];
    	
	var _timerCountdown = null;
	
	var _doubleUppedPosition = null;
	
	var _rolloveredPosition = null;
	
	var _sellPosition      = null;
	/*
	 * position that currently shown on positionDialog
	 */
	var _detailsPosition = null;
    
    /* platform mode 
     * 1. regular
     * 2. floatingWebTrader (Leverate integration)
     */
     var _integrationMode = integrationMode || 'regular';
	
     var _makePositionDomSelectors = null;
     
     var _dialogYaxesOffset = null;
     
     var _cancelPositionDomSelectors = 'form#platformForm .cancelForm';                               
           
	var that = this;
	//public properties	
		//dialogs
		//main dialog box
	this.dialogObj = null;
		//error dialog box
	
	this.dialogError = null;
	//sell dialog box
	this.dialogSell  = null;
	//double up dialog box
	this.dialogDoubleUp = null;
		//rollover dialog box
	this.dialogRollover = null;
		//positions details dialog
	this.dialogPositionDetails = null;
	
	this.loginDialog = null;
	//instance of currently open graph
	this.graph = null;
         
	//public methods
	
    this.getPlatformMode = function(){
        return _integrationMode;
    }
    
	//domReady need to be loaded before the init function
	//because of trading approach, otherwise 
	//if we use init function to initialize events, the dom won't be ready
	this.domReady = function(){
		
		/* bind events */
		//bind move graph feature event
		$('input.moveGraph').click(that.moveGraph);
		$('div.moveQty select').change(that.updateMoveGraphOffset);
		
		//bind click event "call"  button
		$('input[name="putPlatform"]').bind('click', {position: 'put'}, that.changePositionDirection);
		//bind click event "put"  button
		$('input[name="callPlatform"]').bind('click', {position: 'call'}, that.changePositionDirection);
		/* bind "approve" button in "cancel form" */
		$('input.platformApprove').bind('click',{}, that.approveButtonPressed);
		/* bind "cancel" button in "cancel form" */
		$('input.platformCancel').bind('click',{}, that.cancelButtonPressed);
		
		$('input.amountPlatform').bind('keyup',{}, that.onAmountChange);
       
		setTimeout(init, 0);
		//init();
	}

	this.getCustomer = function (){
		return _customer;
	}
	/*
	 * updates _options -> delete expired, load options that opened
	 */
	this.updatePageOptions = function(){
		
		//get all open option for current asset from db
		var openOptions = _selectedAsset.loadOptions('open', 'endDate', false);
		
		//delete expired options
		_optionsIds = new Array();

		for(key = _options.length -1; key >-1 ; key --){
			
			if(typeof key != 'function'){
				if(_options[key].getStep() == 'expired'){
					_options[key].destruct();
					_options.splice(key, 1);
				}
				else{
					_optionsIds.push(_options[key].id);
				}
			}
			
		}
		
		
		//creating list of recently opened option
		//and update the _options ad the select element that contains open option
		var optionsArrayForOptionsSelect = new Object();
		$.each(openOptions, function(key, openOption){
			var ansInArray = jQuery.inArray(openOption.id, _optionsIds);
			
			if(typeof ansInArray == 'undefined' || ansInArray == -1){
				_options.push(new Option(false, openOption, {assetId: _selectedAsset}, 'platform', 'open', 
															{'beforeExpiry': optionBeforeExpiry, 'closedForNewPosition': optionClosedForNewPosition, 
					   										'expired': optionExpired}));
				optionsArrayForOptionsSelect[openOption.id] = openOption.endDate;
			}
		});
		
		//return array of options that was opened since last update
		return optionsArrayForOptionsSelect;
		
	}
	
	this.onAmountChange = function(){
		//get investment amount
        var investment = parseInt($('form#platformForm input.amountPlatform').val());
            
		//return value is Array -> Array[0] -> profit, Array[1] -> loss
		var profitAndLoss = _selectedOption.calculateProfitLoss(investment);
		
        $('form#platformForm .potentialPayout').text(profitAndLoss[0] + AppData.accountCurrency);
        $('form#platformForm .protectedAmount').text(profitAndLoss[1] + AppData.accountCurrency);
	}
	
	this.moveGraph = function(e){
		var timeUnit  = $(e.target).attr('timeunit');
		var direction = $(e.target).attr('direction');
		var offset = $(e.target).attr('offset');
		_selectedOption.graph.move(timeUnit, offset, direction)
	}
	
	this.updateMoveGraphOffset = function(e){
		var select = $(e.target);
		$('input.' + select.attr('related')).attr('offset', select.val());
	}
	/**
	 * creating array of options [id]=value and insert 
	 * it into <select> with View.select method
	 */
	this.appendOptionsSelect = function(){
		
		var optionsArrayForOptions = new Object();
		
		if($('select#optionsPlatformSelect').size()){
			$('select#optionsPlatformSelect').remove();
		}
		
		
		$.each(_options, function(key, option){
			optionsArrayForOptions[' ' + option.id] = option.endDate;
		});
		
		View.select(false, false, _selectedOption.id, optionsArrayForOptions, 
								  {name: 'optionsPlatformSelect', id: 'optionsPlatformSelect'}, 
								  onChangeOption, 'labelForOptions', 'after', false);
       
	}
	
	this.apendAssetsSelect = function(){
		
	}
	
	this.changePositionDirection = function(e){
		
		var targetButton = $(e.target);
		var inputPosition = $('input[name="position"]');
		//set correct value to input field in position form
		inputPosition.val(e.data.position);
		//add slected class to apropriate button
		$('input.putPlatform, input.callPlatform').removeClass('selected')
		targetButton.addClass('selected');
		
		$('img.formDirectionImage').attr('src', 'appProxy/platform/' + e.data.position +  'Sign.png')
								   .removeClass('hidden');
		
		_newPosition.position = e.data.position;
		
		if(AppData.isLoggedIn){
			//Customer clicks for risk management
			$.post(AppData.url + AppData.pageId + '/selectedPositionTrack',
					{assetId: _selectedAsset.id ,direction: e.data.position, optionId: _selectedOption.id},
					{},
					'json');
		}
	}
	
	this.initNewPosition = function(){
		_newPosition = new PositionPlatform(false, {optionId: _selectedOption, customerId: _customer}, false, 'new', 
				{'valid': newPositionValid, 'notValid': newPositionNotValid, 
				 'saved': newPositionSaved, 'open': newPositionOpened, 'canceled': newPositionCanceled, 'expired':Flow.onPositionExpired}, 
				 {'rateChanged': Flow.onPositionNewRateRecieved, 'payoutCalculated': Flow.onPositionCurrentPayoutCalculated});
		
		_newPosition.assetName     = _selectedAsset.name;
		_newPosition.optionEndDate = _selectedOption.endDate;
        
        updatePayoutPercentage();
	}
	
	/** "cancel form handlers" */
	this.approveButtonPressed = function(){
		_newPosition.cancelCountdownEnded();
	}
	
	this.cancelButtonPressed = function(){
		_newPosition.cancel();
	}
	/** end of "cancel form" handlers **/
	
	/** platform time **/
	
	this.updatePlatformTime = function(){
		var timeString = $('#LShour').text()    + ':' + 
						 $('#LSminute').text()  + ':' +
						 $('#LSseconds').text() + ' ' +
						 $('#timezone').text()  + ' ' +
						 $('#LSdate').text();
		$('#platformTime').text(timeString);
	}
	
	this.restartTimerCountdown = function(){
		if(_timerCountdown && typeof _timerCountdown == 'object')
			_timerCountdown.destruct();
		else
			_timerCountdown = new Countdown();
		_timerCountdown.init(24*60*60, that.restartTimerCountdown, null, that.updatePlatformTime);
	}
	/**
	 * updating the position of dialog,
	 * it's necessary because the position may move regarding y-axes
	 * and we need to new coordinates of the position and move the dialog accordindly
	 */
	this.updateDialogsPositions = function(){
		var dialogsObj = {
				'doubleUp': {
					'container': 		that.dialogDoubleUp,
					'relatedPosition': _doubleUppedPosition
				},
				'rollover': {
					'container':   		that.dialogRollover,
					'relatedPosition':	_rolloveredPosition
				},
				'positionDetails': {
					'container': 		that.dialogPositionDetails,
					'relatedPosition':	_detailsPosition	
				},
				
				'sell':{
					'container':        that.dialogSell,
					'relatedPosition':  _sellPosition
				}
				
		}
		
		$.each(dialogsObj, function(key, dialogObj){
			
			if(dialogObj.container.dialog('isOpen')){
				var offest = _selectedOption.graph.calculateGlobalPointOffset(iOkun.strtotime(dialogObj.relatedPosition.date) * 1000 
								+ General.browserOffset, dialogObj.relatedPosition.rate);
								
				dialogObj.container.parent()
                                                    .css({position: 'absolute', 
                                                          top: offest.top  - _dialogYaxesOffset , 
                                                          left: offest.left});
			}
		});

	}
	/*
	 * changes the asset select and option select 
	 * according to given asseetId and optionId
	 */
	this.loadGraph = function(assetId, optionId, callbackFunction){
		//get assetSelect and optionSelectElemnts
		
		var assetsPlatformSelectElem = $('#assetsPlatformSelect');
		var optionsPlatfromSelectElem = $('select#optionsPlatformSelect');
		
		if(assetsPlatformSelectElem.find('option:selected').val() != assetId){
			that.dialogLoading.dialog('open');
			assetsPlatformSelectElem.find('option:selected')
											.attr('selected', false)
											.end()
											.find('option[value="' + assetId + '"]')
											.attr('selected', true)
											.end()
											.change();
		}
		//change option to option of double upped position
		var outerTimeout = setTimeout(function assetLoaded(){
			
			if($('#assetsPlatformSelect').find('option:selected').val() == _selectedAsset.id && $('select#optionsPlatformSelect').find('option:selected').val() == _selectedOption.id && that.graph.isPlotReady()){
				
				if($('select#optionsPlatformSelect').find('option:selected').val() != optionId){
					$('select#optionsPlatformSelect').find('option:selected')
					.attr('selected', false)
					.end()
					.find('option[value="' + optionId + '"]')
					.attr('selected', true)
					.end()
					.change();
					
					var innerTimeout = setTimeout(function optionLoaded(){
						
						if($('select#optionsPlatformSelect').find('option:selected').val() == _selectedOption.id && that.graph.isPlotReady()){
							that.dialogLoading.dialog('close');
							if(typeof callbackFunction == "function")
								callbackFunction();
							clearTimeout(innerTimeout);
						}
						else{
							innerTimeout = setTimeout(optionLoaded, 500);
						}
					}, 500);
				}
				else{
					that.dialogLoading.dialog('close');
					if(typeof callbackFunction == "function")
						callbackFunction();
				}
				clearTimeout(outerTimeout);
			}
			else{
				outerTimeout = setTimeout(assetLoaded, 500);
			}
		}, 500)
	}
	
	this.drawDialogInTheMiddleOfPlot = function(dialogContainer){
		if(typeof that.graph == "object" && !jQuery.isEmptyObject(that.graph)){
			var graphConrainerOffset = that.graph.getContainerOffset();
			var graphContainerDimentions = that.graph.getContainerDimentions();
		
			
			//dray the dialog in the middle of the plot area
			dialogContainer.parent()
			.css({position: 'absolute', 
				  top:  graphConrainerOffset.top + (graphContainerDimentions['height'] / 2 - dialogContainer.height() / 2), 
				  left: graphConrainerOffset.left + (graphContainerDimentions['width'] / 2 - dialogContainer.width() / 2)});
		}
	
	}
	/**
	 * errors -> array
	 */
	this.showErrors = function(errors){
		$('ul.platformErrorsList li').remove();
		$.each(errors, function(i, errorMessage){
			$('ul.platformErrorsList').append('<li>' + errorMessage + '</li>')
			console.log(errorMessage)
		});
		
		
		that.dialogError.dialog('open');
		that.drawDialogInTheMiddleOfPlot(that.dialogError);
		

	}
	/*
	 * @string posExecTime  - hour:minute:seconds
	 * @string posRate 	    - rate of the position
	 * @string posDirection - call/put
	 * @object point - {'x': xvalue, 'y': yvalue}
	 */
	this.showPositionDetails = function(posExecTime, posRate, posDirection, point){
		//find the position
		
		$.each(_openPositions, function(key, openPosition){
			if(parseInt(openPosition.rate) == parseInt(posRate) && openPosition.position == posDirection && openPosition.dateMS == point['x']){
				_detailsPosition = openPosition;
			}
		});
		
		//insert content
		that.dialogPositionDetails.find('#platfromPositionDetailsType').text(posDirection + ' ')
								  .append($('<img>').attr('src', 'sysProxy/platform/' + posDirection + 'Sign.png'))
								  .end()
								  .find('#platfromPositionDetailsExecTime').text(posExecTime)
								  .end()
								  .find('#platfromPositionDetailsRate').text(posRate)
								  .end()
								  .find('input.platformPositionRolloverBtn, input.platformPositionDoubleUpBtn').attr('positionId', _detailsPosition.id)
								  .end()
								  .attr('optionid', _detailsPosition.optionId.id)
		
		var offset = _selectedOption.graph.calculateGlobalPointOffset(point['x'], point['y']);
	
		that.dialogPositionDetails.dialog('open');
		
		if(_detailsPosition.optionId.getStep() == 'closedForNewPosition'){
			//disable double up
			that.changeDoubleUpRolloverStatus('disable', _detailsPosition.optionId.id, 'DoubleUp');
		}
		
		that.dialogPositionDetails.parent()
		.css({position: 'absolute', 
			  top:  offset.top  - _dialogYaxesOffset, 
			  left: offset.left});
	}
	
	/*
	 * status = 'enable'/'disable'
	 */
	this.changeDoubleUpRolloverStatus = function(status, optionId, className, positionId){
		var positionId = positionId || false;
			
		var smallBtn = (positionId) ?  $('div#platformOpenPositions ul#platformPosition_' + positionId + ' input.platform' + className) 
									: $('div#platformOpenPositions ul[optionid="' + optionId + '"] input.platform' + className);
		
		if(status == 'enable'){
			smallBtn.attr({'class': 'platform' + className + ' ' + status, 'disabled': false});
		}
		else{
			smallBtn.attr({'class': 'platform' + className + ' ' + status, 'disabled': true});
			//close dialog if open
			if(eval('that.dialog' + className + '.find("input.rolloverApprove").attr("positionId")') == positionId) {
				//if the dealog related to position, close it
				eval('that.dialog' + className + '.dialog("close")');
			}
			//all positions related to the option disabled
			if(!positionId && className != 'Sell'){
				eval('that.dialog' + className + '.dialog("close")');
			}
		}		
		
		
		//handle positiondetails popoup
		if(that.dialogPositionDetails.dialog('isOpen') && 
				that.dialogPositionDetails.attr('optionid') == optionId && 
				that.dialogPositionDetails.find('input#openRollover').attr('positionId') == positionId){
			var btn = that.dialogPositionDetails.find('input#open' + className);
			if(status == 'enable'){
				btn.attr({'class': 'platformPosition' + className + 'Btn' + ' ' + status, 'disabled': false});
			}
			else{
				btn.attr({'class': 'platformPosition' + className + 'Btn' + ' ' + status, 'disabled': true});
			}	
		}
	}
	
	this.destructor = function(){
		if(!$.isEmptyObject(_selectedOption)){
			_selectedOption.destruct();
		}
		$('div#positionsContainer ul').remove();
		
//		_customer        = null;
//		
//		_selectedAsset   = null;
//		
//		_options = null;
//		
//		_newPosition = null;
		
	}
	
	this.updatePopularity = function(callPerc){
		//update the bar
		$('div.tradersPlatformBar div').css('width', callPerc + '%');
		//update the percentage
		$('strong#upPopularityPlatform').text(callPerc + '%');
		$('strong#downPopularityPlatform').text((100 -callPerc) + '%');
	}
	
	//private methods
	var init = function(){
        //init variables that depends on integration mode
        if(_integrationMode == 'regular'){
            _makePositionDomSelectors = 'form#platformForm .makePositionForm';
            _dialogYaxesOffset = 22;
        }
        else{
            _makePositionDomSelectors = 'form#platformForm .platformHeadInvestmentAmountWrapper, form#platformForm .platformHeadInvestmentWrapper';
            _dialogYaxesOffset = 0;
        }
        //end of variable init
         
		var assetsArrayForSelect = new Object();
		//first asset from tradeable assets will be the selected asset
		var byPassInner = false;
		
		$.each(AppData.tradableAssets, function(type, assetsByType){	
			if(typeof assetsByType == 'object'){//when some of the asset types (stocks, currencies...) is empty, 
										// assetsByType variable is not an array
				
				$.each(assetsByType, function(id, name){
					if(!byPassInner){
						_selectedAsset = new Asset(id);
						that.updatePopularity(_selectedAsset.popularity);
						byPassInner = true;
					}
					assetsArrayForSelect[id] = {'value': name, 'group': AppData.langHome[type.toLowerCase()]};
				});
			}
		});
		//init error popup
		that.dialogError = $('div#platformErrorContainer').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	303,
			height:   		105,
			zIndex: 		2000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformError'
		});
		
		that.dialogError.find('div.platformErrorClose').bind('click', {}, function(){
			that.dialogError.dialog('close');
		});
		//validate that trading available
		if(jQuery.isEmptyObject(assetsArrayForSelect)){
			//no tradable assets exists
			that.showErrors([langErrors.noTrading]);
			
			return;
		}
		
		//make and insert into the doom asset select box
		View.select(false, false, _selectedAsset.id, assetsArrayForSelect, 
								  {name: 'assetsPlatformSelect', id: 'assetsPlatformSelect'}, 
								  onChangeAsset, 'labelForAssets', 'after', false, true);
        
		//get all open options that related to selected asset
		
		_options = _selectedAsset.loadOptions('open', 'endDate', true, 'open', 
											  {'beforeExpiry': optionBeforeExpiry, 'closedForNewPosition': optionClosedForNewPosition, 
											   'expired': optionExpired});
		
		//initilize selected option
		_selectedOption = _options[0];
		_selectedOption.assetId = _selectedAsset;
		
		
		//append options select to the page
		that.appendOptionsSelect();
	
		//make and insert into the doom asset select box
		if(AppData.isLoggedIn){
			_customer = Customer.getCurrent();//get current customer
			_openPositions = _customer.getCustomerPositions('open', true);
			
			if(_openPositions.length){
				//update callbacks
				$.each(_openPositions, function(key, openPosition){
					openPosition.optionId.setStepChangeCallbacks({'beforeExpiry': optionBeforeExpiry, 
																  'closedForNewPosition': optionClosedForNewPosition, 
																  'expired': optionExpired});
				});
				
				// if user has open positions,
				// recieve them from db
				// and append to appropriate place in the html	
				var positionsListHtml = PositionPlatform.createOpenPositionsList(_openPositions);
				$('#positionsContainer').append(positionsListHtml);
				//show postion container, because there is open positions
				$('#platformOpenPositions').removeClass('hidden');
				
				//bind double up and rollover events
				$('div#positionsContainer input.platformDoubleUp').live('click', {}, onDoubleUpClick);
				$('div#positionsContainer input.platformRollover').live('click', {}, onRolloverClick);
				
				//bind selll event
				$('div#positionsContainer input.platformSell').live('click', {}, onSellClick);
				
				
			}
		}
		
		//initilize position in "new" step
		that.initNewPosition();
		
		//prints option graph			
		_selectedOption.initGraph('platformGraph', '.platformFeed');
		
		
		
		that.restartTimerCountdown();
		//set callback function for options that 
		//it positions no more availible for rollover
		Option.noRolloverCallback = noRolloverCanBeMade;
		
		Option.onSellStatusChangedCallback = sellStatusChanged;
		
		Graph.onPositionClickCallback = that.showPositionDetails;
		
		
		
		//init sell dialog
		that.dialogSell = $('div#platformSellDialog').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	214,
			height:   		187,
			zIndex: 		3000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformSell'
		});
		that.dialogSell.find('div.platformErrorClose, input.sellCancel').bind('click', {}, onSellCancel);
		that.dialogSell.find('input.sellApprove').bind('click', {}, onSellApprove);

		//init double up dialog
		
		that.dialogDoubleUp = $('div#platformDoubleUpDialog').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	214,
			height:   		187,
			zIndex: 		3000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformDoubleUp'
		});
		
		that.dialogDoubleUp.find('div.platformErrorClose, input.doubleUpCancel').bind('click', {}, function(){
			that.dialogDoubleUp.dialog('close');
			_doubleUppedPosition = null;
		});
		that.dialogDoubleUp.find('input.doubleUpApprove').bind('click', {}, onDoubleUpApprove);
		
		
		//init rollover dialog
		
		that.dialogRollover = $('div#platformRolloverDialog').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	214,
			height:   		187,
			zIndex: 		3000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformRollover'
		});
		
		that.dialogRollover.find('div.platformErrorClose, input.rolloverCancel').bind('click', {}, function(){
			that.dialogRollover.dialog('close');
			_rolloveredPosition = null;
		});
		
		that.dialogRollover.find('input.rolloverApprove').bind('click', {}, onRolloverApprove);
		
		//init position details dialog
		that.dialogPositionDetails = $('div#platfromPositionDetails').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	213,
			height:   		140,
			zIndex: 		3000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformPositionDialog'
		});
		
		that.dialogPositionDetails.find('div.platformErrorClose').bind('click', {}, function(){
			that.dialogPositionDetails.dialog('close');
			_detailsPosition = null;
		});
		
		//init login dialog
		that.loginDialog = $('#platformOpenAccountContainer').dialog({
			autoOpen: 		false,
			modal:    		true,
			width:   	 	209,
			height:   		174,
			zIndex: 		3000,
			resizable: 		false,
			draggable: 		false,
			dialogClass: 	'tradingPlatformLogin',
			open: function(event, ui){

				flowPage.drawDialogInTheMiddleOfPlot(flowPage.loginDialog);
			}
		});
		
		that.loginDialog.find('div.platformErrorClose').bind('click', {}, function(){
			that.loginDialog.dialog('close');
		});
		that.loginDialog.find('input[name="passwordFake"]"').bind('focus', {container: '#platformOpenAccountContainer'}, General.onFocusPassword);
		that.loginDialog.find('input[name="password"]').bind('blur', {container: '#platformOpenAccountContainer'}, General.onBlurPassword);
		that.loginDialog.find('input[name="email"]').focus(General.onFocusEmail)
													.blur(General.onBlurEmail);
													
		
		//bind rollover btn on position details dialog
		that.dialogPositionDetails.find('input.platformPositionRolloverBtn').bind('click', {}, function(){
			that.dialogPositionDetails.dialog('close');
			onRolloverClick.apply(that.dialogPositionDetails.find('input.platformPositionRolloverBtn'));
			_detailsPosition = null;
		});
		//bind double up btn on position details dialog
		that.dialogPositionDetails.find('input.platformPositionDoubleUpBtn').bind('click', {}, function(){
			that.dialogPositionDetails.dialog('close');
			onDoubleUpClick.apply(that.dialogPositionDetails.find('input.platformPositionDoubleUpBtn'));
			_detailsPosition = null;
		});
		
	
	}
	
	/*
	 * double up handlers
	 * @returns
	 */
	/**
	 * click on small button (positions lines)
	 */
	var onDoubleUpClick = function(e){
		var doubleUppedPositionId = $(this).attr('positionid');
		that.dialogDoubleUp.find('input.doubleUpApprove').attr('positionid', doubleUppedPositionId);
		
		//get double upped position from open positions array
		$.each(_openPositions, function(key, openPosition){
			if(openPosition.id == doubleUppedPositionId){
				_doubleUppedPosition = openPosition;
				return false;
			}
		});
		
		
		var platformReady = function(){
			var doubleUppedPositionOffest = _selectedOption.graph.calculateGlobalPointOffset(iOkun.strtotime(_doubleUppedPosition.date) * 1000 + General.browserOffset, _doubleUppedPosition.rate);
			//open the dialog box
			that.dialogDoubleUp.dialog('open');
				
			that.dialogDoubleUp.parent()
							.css({position: 'absolute', 
								  top: doubleUppedPositionOffest.top  - _dialogYaxesOffset, 
								  left: doubleUppedPositionOffest.left});
			 _selectedOption.graph.setRedrawCompletedCallback(that.updateDialogsPositions);
		}
		
		that.loadGraph(_doubleUppedPosition.optionId.assetId.id, _doubleUppedPosition.optionId.id, platformReady);
	}
	
	var onDoubleUpApprove = function(e){
		
		_newPosition.amount   = _doubleUppedPosition.amount;
		_newPosition.position = _doubleUppedPosition.position;
		_newPosition.errors   = false;
		_newPosition.step     = 'valid';
		
		that.dialogDoubleUp.dialog('close');
		
		newPositionValid();
		
		_doubleUppedPosition = null;
		
		_selectedOption.graph.setRedrawCompletedCallback(null);
	}
	
	/**
	 * rollover handlers
	 * @returns
	 */
	var onRolloverClick = function(e){
		var rolloveredPositionId = $(this).attr('positionid')
		that.dialogRollover.find('input.rolloverApprove').attr('positionid', rolloveredPositionId);
		
		//get double upped position from open positions array
		$.each(_openPositions, function(key, openPosition){
			if(openPosition.id == rolloveredPositionId){
				_rolloveredPosition = openPosition;
				return false;
			}
		});
		
		var platformReady = function(){
			//insert data into rollover dialog
			var currentDateParts = iOkun.convertUnixTime(iOkun.getCurrentTime());
			var selectedOptionEndDateParts = iOkun.fetchPartsFromTimestampString(_selectedOption.endDate);
			that.dialogRollover.find('#platformRolloverCurrentExpireTime')
							   .text(selectedOptionEndDateParts['hour'] + ':' + selectedOptionEndDateParts['minute'])
							   .end()
							   .find('#platformRolloverCurrentInvestment').text(_rolloveredPosition.amount + AppData.accountCurrency);
			var posibleOptions = new Object();
			var totalPosibleOptions = 0;
			
			$.each(_options, function(key, option){
				
				var endDateParts = iOkun.fetchPartsFromTimestampString(option.endDate);
				var optionValid = true;
				//posible option must end after the position option
				
				if(_selectedOption.endDateMS >= option.endDateMS){
					optionValid = false;
					
				}
				//posible option must end today
				if(currentDateParts['year'] != endDateParts['year'] || 
				   currentDateParts['month'] != endDateParts['month'] || 
				   currentDateParts['day'] != endDateParts['day']){
				   optionValid = false;
				}
				if(optionValid){
					posibleOptions[option.id] = endDateParts['hour'] + ':' + endDateParts['minute'];
					totalPosibleOptions ++;
				}
			});
			
            if(AppData.siteOptions['lastDayOptionRollover']['value'] == '' && totalPosibleOptions >= 1){ //remove last option
				//posibleOptions.slice(0, totalPosibleOptions - 1);//remove the last option
				var counter = 0;
				$.each(posibleOptions, function(optionId, endDate){
					counter ++;
					if(counter == totalPosibleOptions){
						delete posibleOptions[optionId];
						totalPosibleOptions--;
					}
				});
			}
			
			if(totalPosibleOptions){
			
				View.select(false, false, false, posibleOptions, 
						  {name: 'platformRolloverFutureExpire', id: 'platformRolloverFutureExpire'}, 
						  false, 'platformFutereExpireContainer', 'append', false);
				
				//calculate position point offset
				var rolloveredPositionOffest = _selectedOption.graph.calculateGlobalPointOffset(iOkun.strtotime(_rolloveredPosition.date) * 1000 
												+ General.browserOffset, _rolloveredPosition.rate);
				//open the dialog box
				that.dialogRollover.dialog('open');
					
				that.dialogRollover.parent()
								.css({position: 'absolute', 
									  top: rolloveredPositionOffest.top  - _dialogYaxesOffset, 
									  left: rolloveredPositionOffest.left});
				 _selectedOption.graph.setRedrawCompletedCallback(that.updateDialogsPositions);
			}
			else{
				that.showErrors([AppData.langHome.noFuturesExpiries]);
				_rolloveredPosition = null;
			}
		}
		
		that.loadGraph(_rolloveredPosition.optionId.assetId.id, _rolloveredPosition.optionId.id, platformReady);
		
	}
	
	var onRolloverApprove = function(e){
		var rolloverDone = function(data){
			if(data['status'] == "true"){ //rollover succeded
				var newPositionLine = PositionPlatform.createOpenPositionRecord(_rolloveredPosition, true);
				$('ul#platformPosition_' + _rolloveredPosition.id).remove();
				$('div#positionsContainer').append(newPositionLine);
				//update _openPosition array with roolovered position
				$.each(_openPositions, function(key, openPosition){
					if(openPosition.id == _rolloveredPosition.id){
						_openPositions[key] = _rolloveredPosition;
						return false;
					}
				});
				that.loadGraph(_rolloveredPosition.optionId.assetId.id, _rolloveredPosition.optionId.id, false);
				_rolloveredPosition = null;
				that.dialogRollover.dialog('close');
			}
			else{//rollover failed
				that.showErrors([data['status']]);
			}
		}
		
		var selectedOptionId = that.dialogRollover.find('select#platformRolloverFutureExpire option:selected').val();
		$.each(_options, function(key, option){
			if(option.id == selectedOptionId){
				_rolloveredPosition.rollover(option, rolloverDone);
				return false;
			}
		});
		
		
	}
	
	var onSellClick = function(e){
		if(_sellPosition){ //prevent calling method getBuyMeOutPrice twice
						  // it happens where sell button clicked couple of times
			return;
		}
		var sellPositionId = $(this).attr('positionid')
		that.dialogSell.find('input.sellApprove').attr('positionid', sellPositionId);
		
		//get double upped position from open positions array
		$.each(_openPositions, function(key, openPosition){
			if(openPosition.id == sellPositionId){
				_sellPosition = openPosition;
				return false;
			}
		});
		var platformReady = function(){
		
			var sellPositionOffest = _selectedOption.graph.calculateGlobalPointOffset(iOkun.strtotime(_sellPosition.date) * 1000 + General.browserOffset, _sellPosition.rate);
			//open the dialog box

			var priceRecieved = function(){
				if(_sellPosition.buyMeOutStatus){
					//update buyMeOutPrice
					$('span#platformWaitForAmount').addClass('hidden');
					$('span#platformSellAmount').text(_sellPosition.buyMeOutPrice + AppData.accountCurrency)
												.removeClass('hidden');
					$('#platformSellDialog input.sellApprove, #platformSellDialog input.sellCancel, div.platformSellCountdownContainer')
												.removeClass('hidden')
					//open the dialog
					
					
					//init the countdown
					_sellPosition.buyMeOutCountdown.init(5, 'sellCountdown', onSellCancel, false, true);
				}
				else{
					
					that.showErrors([_sellPosition.errors]);
					_sellPosition = null;
				}
				
			};
			that.dialogSell.dialog('open');
			that.dialogSell.parent()
							.css({position: 'absolute', 
								  top: sellPositionOffest.top  - _dialogYaxesOffset, 
								  left: sellPositionOffest.left});
			_selectedOption.graph.setRedrawCompletedCallback(that.updateDialogsPositions);
			
			_sellPosition.getBuyMeOutPrice(priceRecieved)
			
		}
		that.loadGraph(_sellPosition.optionId.assetId.id, _sellPosition.optionId.id, platformReady);
	}
	
	var onSellApprove = function(){
		
		var buyMeOutCompleted = function(){
			//destruct the countdown
			_sellPosition.buyMeOutCountdown.destruct();
			//close the dialog box
			that.dialogSell.dialog('close');
			
			if(_sellPosition.buyMeOutStatus){
				//remove the point from  the graph
				_selectedOption.graph.removePoint([_sellPosition.dateMS, _sellPosition.rate], _sellPosition.position);
				
				for(key = _openPositions.length -1; key >-1 ; key --){
					if(typeof key != 'function'){
						if(_openPositions[key].id == _sellPosition.id){
							_openPositions[key].setStep('expired');//sold treated as expired for now
							_openPositions.splice(key, 1);
						}
					}
				}
			}
			else{
				that.showErrors([_sellPosition.errors]);
			}
			_sellPosition = null;
		} 
		resetSellDialog();
		_sellPosition.buyMeOut(buyMeOutCompleted);
	}
	/*
	 * called when timeout or cancel button pressed
	 */
	var onSellCancel = function(){
		console.log(that.dialogSell.dialog('isOpen'))
		resetSellDialog();
		that.dialogSell.dialog('close');
		_sellPosition.buyMeOutCountdown.destruct();
		_sellPosition = null;
	}
	
	var resetSellDialog = function(){
		$('span#platformWaitForAmount').removeClass('hidden');
		$('span#platformSellAmount').text('').addClass('hidden');
		$('#platformSellDialog input.sellApprove, #platformSellDialog input.sellCancel, div.platformSellCountdownContainer').addClass('hidden');
	}
	/*
	 * Fired when asset change
	 */
	var onChangeAsset = function(e){
		
		
		//get new assetId
		var newSelectedAssetId = $(e.target).find('option:selected').val();
		
		//update current selected asset
		_selectedAsset = new Asset(newSelectedAssetId);
		//update popularity
		that.updatePopularity(_selectedAsset.popularity);
		//update related to the new asset options
		_options = _selectedAsset.loadOptions('open', 'endDate', true, 'open', 
				  							  {'beforeExpiry': optionBeforeExpiry, 'closedForNewPosition': optionClosedForNewPosition, 
			   								   'expired': optionExpired});
		//destruct old graph
		_selectedOption.graph.destruct();
		
		//initilize selected option
		_selectedOption = _options[0];
		_selectedOption.assetId = _selectedAsset;
		
		//update current option that related to new position
		_newPosition.optionId = _selectedOption;
		
		//append options select to the page
		that.appendOptionsSelect();
		
		that.initNewPosition();
		
		
		//prints option graph
		_selectedOption.initGraph('platformGraph', '.platformFeed');
		
		
	}
	
	/*
	 * Fired when option changed
	 */
	var onChangeOption = function(e){
		
		//get new optionId
		var newSelectedOptionId = $(e.target).find('option:selected').val();
		
		
		//destruct old graph
		_selectedOption.graph.destruct();
		
		//initilize selected option
		_selectedOption = new Option(newSelectedOptionId, false, {assetId: _selectedAsset}, 'platform');
		
		//update current option that related to new position
		that.initNewPosition();
		
		//prints option graph	
		_selectedOption.initGraph('platformGraph', '.platformFeed');
		
	}
	
	var updatePayoutPercentage = function(){
       
        var profitText = '';
        
        if (_integrationMode == 'regular')
            profitText = _selectedOption.profit + '%';  /* for regular white labels */
        else if (_integrationMode == 'floating')
            profitText = _selectedOption.profit;        /* for Leverate integration */
        else
            profitText = _selectedOption.profit + '%';  /* default */
        
        $('#platformPayout').text(profitText);
	}
	
	/*
	 * positions step change callbacks
	 */
	/**
	 * called when step set to "valid"
	 */
	var newPositionValid = function(){
		
		//update _position currency
		
		//if customer is logged continue,
		//otherwise, show login dialog
		//and set step to new
		if(_customer){
			_newPosition.currency = _customer.currency;
			
			_newPosition.make();
			//Risk managment
			$.post(AppData.url + AppData.pageId + '/selectedPositionTrack',
					{assetId: _selectedAsset.id, direction: _newPosition.position},
					{},
					'json');
		}
		else{
			_newPosition.setStep('new');
			that.loginDialog.dialog('open');
		}
	}
	
	/**
	 * called when step set to "notValid"
	 */
	var newPositionNotValid = function(){
		//clear errors
		$('ul.platformErrorsList li').remove();
		that.showErrors(_newPosition.errors);
		//append new errors
//		$.each(_newPosition.errors, function(i, errorMessage){
//			$('ul.platformErrorsList').append('<li>' + errorMessage + '</li>')
//			console.log(errorMessage)
//		});
//		
//		that.dialogError.dialog('open');
	}
	/**
	 * called when step set to "saved"
	 */
	var newPositionSaved = function(){
		/* hide "make position" form */
		
        $('form#platformForm').find('.formExpirationDate').text(_selectedOption.endDate)
                                .end()
                                .find('.formAsset').text(_selectedOption.assetId.name)
                                .end()
                                .find('.formInvestment').text(_newPosition.amount + _newPosition.currency)
                                .end()
                                .find('.formRate').text(_newPosition.rate);
        
		
		$(_makePositionDomSelectors).hide();
        /* show "cancel position" form */
        $(_cancelPositionDomSelectors).show();

        
		/* init countdown */
		_newPosition.countdown.init(3, 'platformCountdownContainer', _newPosition.cancelCountdownEnded);	
		
	}
	/**
	 * called when step set to "open"
	 */
	var newPositionOpened = function(){	
		
		/* show "make positon" form */ 
		$(_makePositionDomSelectors).show();
		/* hide "cancel position" form */
		 $(_cancelPositionDomSelectors).hide();
        
		
		//insert the point
		_selectedOption.graph.insertPosition([_newPosition.dateMS, _newPosition.rate], _newPosition.position);
		//insert newly open position to array that holds all customers open positions
		_openPositions.push(_newPosition);
		
		
		//create html for open positions list
		var positionListHtml = PositionPlatform.createOpenPositionRecord(_newPosition, true);
		//insert the position
		$('#positionsContainer').append(positionListHtml);
		
		//show postion container, because there open positions
		$('#platformOpenPositions').removeClass('hidden');
		
		//bind double up and rollover events
		
		$('div#positionsContainer ul#platformPosition_' + _newPosition.id + ' input.platformDoubleUp')
														  .bind('click', {}, onDoubleUpClick);
		$('div#positionsContainer ul#platformPosition_' + _newPosition.id + ' input.platformRollover')
		  .bind('click', {}, onRolloverClick);
		//bind sell event
		$('div#positionsContainer ul#platformPosition_' + _newPosition.id + ' input.platformSell')
		  .bind('click', {}, onSellClick);
		
		
		
		that.initNewPosition();
		
	}
	/**
	 * called when step set to "canceled"
	 */
	var newPositionCanceled = function(){
		/* show "make positon" form */ 
		$(_makePositionDomSelectors).show();
		/* hide "cancel position" form */
		$(_cancelPositionDomSelectors).hide();
	
		that.initNewPosition();
	}
	
	/**
	 * end of positions step change callbacks
	 */
	
	
	/** option step change callbacks **/
	/**
	 * called when option step set to "beforeExpiry"
	 * this step means thet this is last time to make postions
	 */
	var optionBeforeExpiry = function(option){
		
		/* get <option> that contains selected option */
		 var optionElement = View.getOptionFromSelectByAttribute($('select#optionsPlatformSelect'), 'value', option.id);
        /* show the countdown in <option> element */
		option.countdown.updateOutputElementId(optionElement);
        
        /* get <option> that contains selected option */
//        var optionElement = View.getOptionFromSelectByAttribute($('select#optionsPlatformSelect'), 'value', option.id);
//        /* show the countdown in <option> element */
//        var styledOptionElement = $('div.optionsPlatformSelect li[role="option"]').filter(function(){return $(this).data('value') == optionElement.val()})
//        if(styledOptionElement.hasClass('selected')){
//        console.log('selected')
//        option.countdown.updateOutputElementId($('div.optionsPlatformSelect div.display div.text'));
//        }
//        else{
//        console.log('else')
//        option.countdown.updateOutputElementId(styledOptionElement);
//        }

	}
	/**
	 *  called when option step set to "closedForNewPosition"
	 *  this step means the no positions can be made
	 */
	var optionClosedForNewPosition = function(option){
	
		
		that.changeDoubleUpRolloverStatus('disable', option.id, 'DoubleUp');

	}
	
	var noRolloverCanBeMade = function(option){
		that.changeDoubleUpRolloverStatus('disable', option.id, 'Rollover');
		
	}
	
	var sellStatusChanged = function(option){
		var status = (option.sellPosible) ? 'enable' : 'disable';
		that.changeDoubleUpRolloverStatus(status, option.id, 'Sell');
	}
	/**
	 * called when option step set to "expired"
	 */
	var optionExpired = function(option){
		/* get <option> that contains selected option */
		
		for(key = _openPositions.length -1; key >-1 ; key --){
			if(typeof key != 'function'){
				if(_openPositions[key].optionId.id == option.id){
					_openPositions[key].setStep('expired');
					_openPositions.splice(key, 1);
				}
			}
		}
		
		var optionElement = View.getOptionFromSelectByAttribute($('select#optionsPlatformSelect'), 'value', option.id);
		if(optionElement.size()){//option that expired related to selected asset
			if(_selectedOption.id == optionElement.val()){
				 
				 _selectedOption.destruct();
				 optionElement.remove();
				 //update related to the new asset options
				 //we recieve array [id] => endDate of options
				 //that was opened since last update
				// var recentlyOpenedOptions = that.updatePageOptions(); 
				 //update select element
				 //View.select(false, false, false, recentlyOpenedOptions, false, false, false, false, $('#optionsPlatformSelect'));
				 //trigger onChangeOption method
				
				 $('#assetsPlatformSelect').change();
			 }
			 else{
				 
				 optionElement.remove();
				 //update related to the new asset options
				 //we recieve array [id] => endDate of options
				 //that was opened since last update
				 var recentlyOpenedOptions = that.updatePageOptions(); 
				 //update select element
				 View.select(false, false, false, recentlyOpenedOptions, false, false, false, false, $('#optionsPlatformSelect'));
				 
				
			 }
		}
		else{//option that expired related to open position
			
		}
	}
}
//static methods

/*
 * positions callbacks - rate ready, payout ready
 */

Flow.onPositionNewRateRecieved = function(positionId, currentRate, position){
	  
	  $('ul#platformPosition_' + positionId).attr('class', position.state)
	  										.find('li.platformPositionRate')
	  										.text(currentRate);
	  
	  if(position.rolloverPosible && position.optionId.rolloverPosible){
		 	
		  flowPage.changeDoubleUpRolloverStatus('enable', position.optionId.id, 'Rollover', positionId);
	  }
	  else{	
		  flowPage.changeDoubleUpRolloverStatus('disable', position.optionId.id, 'Rollover', positionId);
	  }
}

Flow.onPositionCurrentPayoutCalculated = function(positionId, currentPayout){
	$('ul#platformPosition_' + positionId + ' li.platformCurrentPayout').text(currentPayout + AppData.accountCurrency);
	Flow.calculateTotalPayout(Flow.calculateTotalInvestment());
}

Flow.calculateTotalPayout = function(investment){
	var className = '';
	var totalPayout = 0;
	$('li.platformCurrentPayout').each(function(){
		var value = parseFloat($(this).text())
		if(!isNaN(value))
			totalPayout += value;
	});
	
	if(investment != totalPayout){
		className = (investment > totalPayout)?  'losing' : 'winning';
	} 
	$('span.platformCurrentProfit').text(totalPayout.toFixed(2) + AppData.accountCurrency).attr('class', 'platformCurrentProfit ' + className);
}

Flow.calculateTotalInvestment = function(){
	var totalInvestment = 0;
	$('li.platformInvestment').each(function(){
		var value = parseFloat($(this).text())
		if(!isNaN(value))
			totalInvestment += value;
	});
	$('span.platformTotalInvetment').text(totalInvestment.toFixed(2) + AppData.accountCurrency)
	return totalInvestment;
}

Flow.onPositionExpired = function(positionId){
	//console.log('onPositionExpired, id = ' + positionId);
	$('ul#platformPosition_' + positionId).remove();
}

//on document ready, load page js
$(document).ready(function() {
	
	flowPage = new Flow(AppData.integrationMode);
	
	langErrors = AppData.floatingPlatformErrorsLang;
	langMain = AppData.floatingPlatformLang;
	
	var timeout = setTimeout(function dateTimeReady(){
		if(General.dateTime){ // load domReady funcion only when dateTime ready
			//create "open platform" button
			
			flowPage.dialogObj =  $('div#tradingPlatformContainer').dialog({
				autoOpen: 		false,
				modal:    		true,
				width:   	 	1000,
				height:   		700,
				resizable: 		false,
				draggable: 		false,
				dialogClass: 	'tradingPlatformDialog',
				open: function(event, ui) {
					
					$(".ui-widget-overlay").addClass('tradingPlatformOverlay');
				}
			});
			
			//init loading popup
			flowPage.dialogLoading = $('div#platfromLoadingContainer').dialog({
				autoOpen: 		false,
				modal:    		false,
				width:   	 	303,
				height:   		105,
				zIndex: 		2000,
				resizable: 		false,
				draggable: 		false,
				dialogClass: 	'tradingPlatformLoading',
				open: function(event, ui){
					//fixes nasty ie bug that for some reason scrools ths page 
					//after platfrom opened
					$('html, body').animate({scrollTop:0}, 'fast');
					flowPage.drawDialogInTheMiddleOfPlot(flowPage.dialogLoading);
				}
			});
			
			//insert "open platform" button to the DOM
			//$('ul.mainCategories').append($('<li><button id="openPlatfrom">Open Platform</button></li>'));
			//bind event for dialog close button
			$('div#tradingPlatformContainer').find('input#platformDialogClose').bind('click', {}, function(){
				flowPage.dialogObj.dialog('close');
				flowPage.destructor();
			});
            
			//bind event to "open platform" button
			
			
            if (flowPage.getPlatformMode() == 'regular'){
                $('#openPlatform').removeClass('hidden').click(function(){
                   
                    flowPage.domReady();
                    flowPage.dialogObj.dialog('open');
                   
                });
            }else if (flowPage.getPlatformMode() == 'floating'){
               
                flowPage.domReady();
                $('#floatingPlatformPlaceholder .sectionBorder').append($('#tradingPlatformContainer').show());
            }
			
			clearTimeout(timeout);
		}
		else
			timeout = setTimeout(dateTimeReady, 500);
	});
	
});
