import {Path} from 'components'		//function type class - using the methods of this class here

export function makeBreadBoardConnectionPointIds (labels) {
	let breadBoardConnectionPointIds = [];
	if (labels !== undefined && labels !== null) {
		labels.map(function (label, index) {
			let temp = '';
			if (label.startsWith('GND') || label.startsWith('SUP')) {
				breadBoardConnectionPointIds.push(label);
			} else {

				temp = label[0] + '_' + label.replace(/\D/g,'');
				temp += (label.charCodeAt(0) >= 65 && label.charCodeAt(0) <= 69 ? 'U' : 'D');
				breadBoardConnectionPointIds.push(temp);
			}
		});
	}
	return breadBoardConnectionPointIds;
}

export function getComponentSlotPositionById (svgId, slotId) {
	let root = document.getElementById(svgId)
	// console.log('slotId ', slotId);
	let slot = document.getElementById(slotId)
	// console.log('slot ', slot);
	let box = slot.getBBox()
	let point = root.createSVGPoint()
	point.x = box.x
	point.y = box.y
	let ctm = slot.getCTM()
	point = point.matrixTransform(ctm)
	point.x = point.x + 3
	point.y = point.y + 3 
	return point
}

export function getSlotIdByPosition (slotPosition) {
	let slotId = -1
	if (slotPosition !== undefined && slotPosition !== null) {
		let transform = "translate("+slotPosition.x+','+slotPosition.y+') rotate(0)'
		let selector = 'g[transform=\"'+transform+'\"]'
		slotId = $(selector).attr('id')
	}
	return slotId
}

export function getSlotNameById (slotId) {
	let slotName = -1
	if (slotId !== undefined && slotId !== null && slotId !== -1) {
		if (slotId.startsWith('GND') || slotId.startsWith('SUP')) {
			slotName = slotId
		} else {
			slotName = slotId[0] + slotId.replace(/\D/g, '')
		}
	}
	return slotName
}

export function getSlotNameByPosition (slotPosition) {
	let slotName = -1
	if (slotPosition !== undefined && slotPosition !== null) {
		let slotId = getSlotIdByPosition(slotPosition)
		if (slotId !== -1 ) {
			slotName = getSlotNameById (slotId)
		}
	}
	return slotName
}

export function getSlotIdByName (slotName) {
	let slotId = -1;
	if (slotName === undefined || slotName === null || slotName.length === 0) {
		return slotId
	}

	if (slotName.startsWith('GND') || slotName.startsWith('SUP')) {
		slotId = slotName
	} else if (slotName.startsWith('AR')) {
		slotId = slotName
	} else {
		 slotId = slotName[0] + '_' + slotName.replace(/\D/g,'')
		 slotId += (slotName.charCodeAt(0) >= 65 && slotName.charCodeAt(0) <= 69 ? 'U' : 'D')
	}
	return slotId
}

export function getComponentsListFromCircuitData (circuitData) {
	let components = []
	if (circuitData !== undefined && circuitData !== null) {
		circuitData.map(function (component) {
			components.push({
				componentId : component.componentId,
				componentName :	component.componentName,
				componentMultimediaURL : component.componentMultimediaURL
			})
		})
	}
	return components
}

export function getComponentDetailsById (componentsDetailsList, componentId) {
	let component = ''
	if (componentsDetailsList !== undefined && componentsDetailsList !== null) {
		for (let i=0;i<componentsDetailsList.length;i++) {
			if ( Number(componentsDetailsList[i].componentId) === Number(componentId)) {
				return componentsDetailsList[i]
			}
		}
		return component
	}
}

export function getComponentDetailsByName (componentsDetailsList, componentName) {
	let component = ''
	if (componentsDetailsList !== undefined && componentsDetailsList !== null) {
		for (let i=0;i<componentsDetailsList.length;i++) {
			if (componentsDetailsList[i].componentName === componentName) {
				return componentsDetailsList[i]
			}
		}
		return component
	}
}


export function getDistanceBetweenTwoPoints (point1, point2) {
	if (arguments.length != 2) {
		console.error('ERROR : getDistanceBetweenTwoPoints takes 2 arguments but '+arguments.length+' given')
		return
	}
	if (point1 === undefined || point2 === undefined ) {
		console.error('ERROR : undefined value(s) given')
		return
	}
	if (point1 === null || point2 === null) {
		console.error('ERROR : null value(s) given')
		return
	}
	let dx, dy
	dx = (point2.x - point1.x)*(point2.x - point1.x)
	dy = (point2.y - point1.y)*(point2.y - point1.y)
	return Math.sqrt(dx + dy)

}

export function getOptionById (options, optionId) {
	let option = -1
	if (options !== undefined && options !== null) {
		for (let i=0;i<options.length;i++) {
			if (Number(options[i].optionId) === Number(optionId)) {
				return options[i]
			}
		}
	}
	return option
}

export function getObjectById (objectList, key, value) {
	let obj = -1
	// console.log('got objectList', objectList, key, value);
	if (objectList !== undefined && objectList !== null) {
		for (let i =0;i<objectList.length;i++) {
			if (objectList[i][key] == value) {
				return objectList[i]
			}
		}
	}
	return obj
}

export function removeOtherOptionsOnBreadBoard (currentStepSelectedOptions, newCircuitData) {
	let {componentId, componentOptionId} = currentStepSelectedOptions
	let selectedComponentDetails = getComponentDetailsById(newCircuitData, componentId)
	let componentOptions = selectedComponentDetails.componentOptions
	if (componentOptions !== undefined && componentOptions !== null) {
		componentOptions.map(function (option, optionIndex) {
			if (Number(option.optionId) !== Number(componentOptionId)) {
				option.slots.map(function (slot, slotIndex) {
					let slotId = getSlotIdByName(slot.slot)
					if (slotId !== -1) {
						$('#'+slotId).css('stroke', 'none')
						$('#'+slotId).attr('class', $('#'+slotId).attr('class').replace(/blink/g, ''))
					}
				})
			} else {
				option.slots.map(function (slot, slotIndex) {
					let slotId = getSlotIdByName(slot.slot)
					if (slotId !== -1) {
						$('#'+slotId).attr('class', $('#'+slotId).attr('class').replace(/blink/g, ''))
					}
				})
			}
		})
	}
}

export function removeOtherComponentOptions (componentId, components) {
	// console.log('entered into funciotn', componentId, components);
	if (components !== undefined && components !== null) {
		// console.log('entered into undefined case');
		components.map(function (component, componentIndex) {
			// console.log('entered into map', component.componentId, componentId);
			if (Number(component.componentId) !== Number(componentId)) {
				// console.log('called ', component.componentId, componentId);
				if (component.componentOptions !== undefined && component.componentOptions !== null) {
					component.componentOptions.map(function (option, optionIndex) {
						option.slots.map(function (slot, slotIndex) {
							let slotId = slot.slot.startsWith('AR') ? slot.slot : getSlotIdByName(slot.slot)
							// console.log('prepared slotId', slotId);
							if (slotId !== -1) {
								$('#'+slotId).css('stroke', 'none')
								$('#'+slotId).attr('class', $('#'+slotId).attr('class').replace(/blink/g, ''))
								if (slotId.indexOf('AR') !== -1) {
									$('#'+slotId).css('fill', 'none')
								}
							}
						})
					})
				}
			}
		})
	}
}

export function removeAllComponentOptions (components) {
	if (components !== undefined && components !== null) {
		components.map(function (component, componentIndex) {
			if (component.componentOptions !== undefined && component.componentOptionId !== null) {
				component.componentOptions.map(function (option, optionIndex) {
					if (option.slots !== undefined && option.slots !== null) {
						option.slots.map(function (slot, slotIndex) {
							let slotId = slot.slot.startsWith('AR') ? slot.slot : getSlotIdByName(slot.slot)
							// console.log('prepared slotId', slotId);
							if (slotId !== -1) {
								$('#'+slotId).css('stroke', 'none')
								$('#'+slotId).attr('class', $('#'+slotId).attr('class').replace(/blink/g, ''))
							}
						})
					}
				})
			}
		})
	}
}

export function highlightComponentOptionById (steps, currentStep, userSelectedStepOptions) {
	// console.log('entered into highlightComponentOptionById');
	if (steps !== undefined && steps !== null && userSelectedStepOptions !== undefined && userSelectedStepOptions !== null) {
		for (let i=0;i<currentStep;i++) {
			let {componentId, stepId, componentOptionId} = userSelectedStepOptions[i]
			let currentStepDetails = getObjectById(steps, stepId)
			let component = getObjectById(currentStepDetails.components, componentId)
			let componentOptions = getObjectById(component, componentOptionId)
			// console.log('currentStepDetails component',componentOptionId, currentStepDetails, component, componentOptions);
			if (componentOptions !== -1) {
				componentOptions.slots.map(function (slot, slotIndex) {
					let slotId = slot.slot.startsWith('AR') ? slot.slot : getSlotIdByName(slot.slot)
					// console.log('prepared slotId', slotId);
					if (slotId !== -1) {
						$('#'+slotId).css('stroke', option.color)
					}
				})
			}
		}
	}
}

export function getSlotPositionXYById (slotId) {
	let transformAttr = $('#'+slotId).attr('transform').split(' ')[0]
	let xy = transformAttr.substring(transformAttr.indexOf('(') + 1, transformAttr.length - 1).split(',').map( (n) => Number(n))
	return {x : xy[0], y : xy[1]}
}

export function linearSearch (list, target) {
	let targetIndex = -1
	if (list !== undefined && list !== null) {
		for (let i=0;i<list.length;i++) {
			if (target === list[i].stepNumber) {
				return i
			}
		}
	}
	return targetIndex
}

export function getImagePathByColorCode (colorCode) {
	let imagePath='/images/IoTy/default.png'
	colorCode = colorCode.toUpperCase()
	switch(colorCode) {
		case '#FF0000':
			imagePath = '/images/IoTy/ic_t_red.png'
			break
		case '#00FF00':
			imagePath = '/images/IoTy/ic_t_green.png'
			break
		case '#000000':
			imagePath = '/images/IoTy/ic_t_black.png'
			break
		default:
			imagePath = '/images/IoTy/default.png'
	}
	return imagePath
}

export function compareObjects (obj1, obj2) {
	if (obj1 === undefined || obj1 === null || obj2 === undefined || obj2 == null) {
		return false
	}
	for (let key in obj1) {
		if (obj1.hasOwnProperty(key) !== obj2.hasOwnProperty(key)) return false
		switch(typeof (obj1[key])) {
			case 'object':
				if (!Object.compare(obj1[key], obj2[key])) return false
				break
			default:
				if ( obj1[key] !== obj2[key]) return false
		}
	}
	for (let key in obj2) {
		if (typeof (obj1[key]) === 'undefined') return false
	}
	return true
}

export function compareStepOptions (possibleStepOptions, userSelectedStepOptions) {
	if (possibleStepOptions === undefined || possibleStepOptions === null) {
		return false
	}
	if (userSelectedStepOptions === undefined || userSelectedStepOptions == null) {
		return false
	}
	// console.log('compareStepOptions',possibleStepOptions, userSelectedStepOptions);
	for (let key in userSelectedStepOptions) {
		if (possibleStepOptions.stepType === 'TYPE_CODE' && possibleStepOptions.hasOwnProperty('blankValue')) {
			return true
		}
		// console.log(userSelectedStepOptions[key], possibleStepOptions[key], userSelectedStepOptions[key] !== possibleStepOptions[key] );
		if (userSelectedStepOptions[key] !== possibleStepOptions[key]) return false
	}
	return true
}

export function verifyWiFiAuth (wifiSettings, userData) {
	// console.log('wifiSettings, userData', wifiSettings, userData);
	if ( wifiSettings === undefined || wifiSettings === null || userData === undefined || userData === null ) {
		return false
	}
	return wifiSettings.ssid === userData.ssid && wifiSettings.password === userData.password
}

export function isComponentAlreadyPlaced (componentList, componentId) {
	if (componentList.length === 0 || componentList === undefined || componentList === null ) {
		return false
	}
	let data = componentList.find(function (obj) {
		if (componentId === obj.props.componentId) {
			return true
		}
		return false
	})
	return data ? true : false
}

export function isStepCompleted (currentStepSelectedOptions) {
	if (currentStepSelectedOptions === undefined || currentStepSelectedOptions === null) {
		return false
	}
	let isStepCompleted = false
	switch (currentStepSelectedOptions.stepType) {
		case 'TYPE_CIRCUIT':
			isStepCompleted = currentStepSelectedOptions.componentOptionId !== -1
			break
		case 'TYPE_CODE':
			if (currentStepSelectedOptions.hasOwnProperty('blankValue')) {
				isStepCompleted = currentStepSelectedOptions.blankValue !== ""
			} else {
				isStepCompleted = currentStepSelectedOptions.blankOptionId !== -1
			}
			break
		case 'TYPE_ROUTER_CONFIG':
			isStepCompleted = true
		default:
			isStepCompleted = false
	}
	return isStepCompleted
}

export function isBlinkDotExists (blinkDots, blinkDotId) {
	for (let i=0;i<blinkDots.length;i++) {
		if (blinkDots[i].props.id === blinkDotId) {
			return i
		}
	}
	return -1
}

export function isComponentExists (componentList, componentId, stepId) {
	// console.log('componentList, componentId, stepId', componentList, componentId, stepId);
	for (let i=0;i<componentList.length;i++) {
		if (componentList[i].props.componentId === componentId && componentList[i].props.stepId === stepId) {
			return i
		}
	}
	return -1
}


export function objectLength (object) {
	return Object.keys(object).length 
}
/*
	Wire placing utils
*/

let TOP_RIGHT_WIRES_STATUS = []
let TOP_LEFT_WIRES_STATUS = []
let BOTTOM_RIGHT_WIRES_STATUS = []
let BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS = []

const ARDUINO_TOP_RELAY_REF_POINT_X = 10
let pushFront = true

function generateWirePathsAvailabilityList (numberOfPaths) {
	let pathAvailabilityList = []
	for(let i=0;i<numberOfPaths;i++) {
		pathAvailabilityList.push({
			pathIndex : i,
			componentId : -1,
			available : true
		})
	}
	return pathAvailabilityList
}

export function getEmptyWireSlot (wireStatusList, componentId) {
	let defaultValue = -1
	let mid = Math.floor(wireStatusList.length/2)
	let midValue = wireStatusList[mid]
	let emptyWireSlot = midValue.available ? midValue : defaultValue
	midValue.available = false
	midValue.componentId = componentId
	if (pushFront) {
		wireStatusList = [midValue].concat(wireStatusList.slice(0,mid)).concat(wireStatusList.slice(mid+1, wireStatusList.length))
		pushFront = false
	} else {
		wireStatusList = wireStatusList.slice(0,mid).concat(wireStatusList.slice(mid+1, wireStatusList.length)).concat([midValue])
		pushFront = true
	}
	return {
		wireStatusList,
		emptyWireSlot
	}
}

export function getReservedWireSlot (wireStatusList, componentId) {
	let defaultValue = -1
	for (let i=0;i<wireStatusList.length;i++) {
		if (!wireStatusList[i].available && wireStatusList[i].componentId === componentId) {
			return wireStatusList[i]
		}
	}
	return defaultValue
}

export function isWireAlreadyPlaced (wireStatusList, componentId) {
	if (wireStatusList.length === 0 || wireStatusList === undefined || wireStatusList === null || componentId === -1) {
		return false
	}
	let data = wireStatusList.find(function (obj) {
		if (componentId === obj.componentId) {
			return true
		}
		return false
	})
	return data ? true : false
}

export function generateWirePathData (slotIds, componentId) {
	// console.log('got slotIds', slotIds);
	if (slotIds === undefined || slotIds === null || slotIds.length === 0) {
		return -1
	}
	// console.log('got slotIds', slotIds);
	let slotPositionLabel = -1,
		slotPositionLabels = []
	const ARDUINO_REF_SLOT_TOP = 'AR_GND1'
	const ARDUINO_REF_SLOT_BOTTOM = 'AR_GND2'
	let ARDUINO_REF_SLOT_POSITION_TOP = getComponentSlotPositionById('svgPanel', ARDUINO_REF_SLOT_TOP)
	let ARDUINO_REF_SLOT_POSITION_BOTTOM = getComponentSlotPositionById('svgPanel', ARDUINO_REF_SLOT_BOTTOM)

	for (let i=0;i<slotIds.length;i++) {
		let slotId = slotIds[i],
			slotPosition = null
		if (slotId.startsWith('AR')) {
			slotPosition = getComponentSlotPositionById('svgPanel', slotId)
			// console.log('slotPosition', slotPosition, ARDUINO_REF_SLOT_POSITION_TOP, ARDUINO_REF_SLOT_POSITION_BOTTOM);
			if ( Math.round(slotPosition.y) === Math.round(ARDUINO_REF_SLOT_POSITION_TOP.y) ) {
				slotPositionLabels.push({groupType : 'ARDUINO_TOP', slotId})
			} else if (Math.round(slotPosition.y) === Math.round(ARDUINO_REF_SLOT_POSITION_BOTTOM.y)) {
				slotPositionLabels.push({groupType : 'ARDUINO_BOTTOM', slotId})
			}
		} else if (slotId.startsWith('relay')) {
			slotPositionLabels.push('RELAY')
		} else if (slotId.startsWith('GND') || slotId.startsWith('SUP') || slotId.endsWith('U') || slotId.endsWith('D')) {
			//realted to breadboard
			slotPosition = getSlotPositionXYById(slotId)
			if (slotId.startsWith('GND_U') || slotId.startsWith('SUP_U')) {
				slotPositionLabels.push({groupType : 'BREADBOARD_TOP', slotId})
			} else if (slotId.startsWith('GND_D') || slotId.startsWith('SUP_D')) {
				slotPositionLabels.push({groupType : 'BREADBOARD_BOTTOM', slotId})
			} else if (slotId.endsWith('U')) {
				slotPositionLabels.push({groupType : 'BREADBOARD_MIDDLE_TOP', slotId})
			} else if (slotId.endsWith('D')) {
				slotPositionLabels.push({groupType : 'BREADBOARD_MIDDLE_BOTTOM', slotId})
			}
		}
	}
	let wirePlacingDetails = getWirePlacingType(slotPositionLabels)
	// console.log('wirePlacingDetails', wirePlacingDetails);
	let path = generateWirePathDataBySlotPositionLabel(wirePlacingDetails, componentId, TOP_RIGHT_WIRES_STATUS.length === 0)
	return path
}


export function getWirePlacingType (slotPositionLabels) {
	// console.log('slotPositionLabels', slotPositionLabels);
	let wirePlacingDetails = -1
	let currentSlotDetails = slotPositionLabels
	let currentSlotLabels = currentSlotDetails.map( (obj) => obj.groupType)
	// console.log('currentSlotLabels', currentSlotLabels, currentSlotDetails.map( (obj) => obj.groupType));
	let index = -1

	if ( (index = currentSlotLabels.indexOf('ARDUINO_TOP')) !== -1 ) {
		let otherIndex = index === 0 ? 1 : 0
		if (currentSlotLabels[otherIndex].startsWith('BREADBOARD')) {
			wirePlacingDetails = {wirePlacingType : 'ARDUINO_TOP_BREADBOARD', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		} else if (currentSlotLabels[otherIndex].startsWith('RELAY')) {
			wirePlacingDetails = {wirePlacingType : 'ARDUINO_TOP_RELAY', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		}
	} else if( (index = currentSlotLabels.indexOf('ARDUINO_BOTTOM')) !== -1 ) {
		let otherIndex = index === 0 ? 1 : 0
		if (currentSlotLabels[otherIndex].startsWith('BREADBOARD')) {
			wirePlacingDetails = {wirePlacingType : 'ARDUINO_BOTTOM_BREADBOARD', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		} else if (currentSlotLabels[otherIndex].startsWith('RELAY')) {
			wirePlacingDetails = {wirePlacingType : 'ARDUINO_BOTTOM_RELAY', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		}
	} else if ( (index = currentSlotLabels.indexOf('RELAY') !== -1)) {
		let otherIndex = index === 0 ? 1 : 0
		if (currentSlotLabels[otherIndex].startsWith('BREADBOARD')) {
			wirePlacingDetails = {wirePlacingType : 'BREADBOARD_RELAY', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		}
	} else {
		if (currentSlotLabels[0] === currentSlotLabels[1]) {
			wirePlacingDetails = {wirePlacingType : 'BREADBOARD_WITHIN_BLOCK', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		} else {
			wirePlacingDetails = {wirePlacingType : 'BREADBOARD_BETWEEN_BLOCKS', slotIds : currentSlotDetails.map( (obj) => obj.slotId)}
		}
	}
		
	return wirePlacingDetails
}

export function generateWirePathDataBySlotPositionLabel (wirePlacingDetails, componentId, generateWirePathsAvailability) {

	if (generateWirePathsAvailability) {
		TOP_RIGHT_WIRES_STATUS = generateWirePathsAvailabilityList(5)
		TOP_LEFT_WIRES_STATUS = generateWirePathsAvailabilityList(5)
		BOTTOM_RIGHT_WIRES_STATUS = generateWirePathsAvailabilityList(5)
		BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS = generateWirePathsAvailabilityList(5)
	}
	let {wirePlacingType, slotIds} = wirePlacingDetails
	let path = -1,
		point1 = null,
		point2 = null,
		emptyWireSlotIndex = -1
	const GAP_BETWEEN_WIRES = 10
	if (slotIds[0].startsWith('AR') || slotIds[0].startsWith('relay')) {
		point1 = getComponentSlotPositionById('svgPanel', slotIds[0])
	} else {
		point1 = getSlotPositionXYById(slotIds[0])
	}

	if (slotIds[1].startsWith('AR') || slotIds[1].startsWith('relay')) {
		point2 = getComponentSlotPositionById('svgPanel', slotIds[1])
	} else {
		point2 = getSlotPositionXYById(slotIds[1])
	}
	switch (wirePlacingType) {
		case 'ARDUINO_TOP_BREADBOARD':
			if (!isWireAlreadyPlaced(TOP_RIGHT_WIRES_STATUS, componentId)) {
				let returnValue = getEmptyWireSlot(TOP_RIGHT_WIRES_STATUS, componentId)
				if (returnValue !== -1) {
					TOP_RIGHT_WIRES_STATUS = returnValue.wireStatusList
					emptyWireSlotIndex = returnValue.emptyWireSlot.pathIndex
				}
			} else {
				let reservedWireSlot = getReservedWireSlot(TOP_RIGHT_WIRES_STATUS, componentId)
				if (reservedWireSlot !== -1) {
					emptyWireSlotIndex = reservedWireSlot.pathIndex
				}
			}
			if (emptyWireSlotIndex === -1) {
				path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			} else {
				path = Path().moveTo(point1.x, point1.y)
						.verticalLineTo(point1.y- (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
						.horizontalLineTo(point2.x)
						.verticalLineTo(point2.y)
			}
			break
		case 'ARDUINO_BOTTOM_BREADBOARD':
			if (!isWireAlreadyPlaced(BOTTOM_RIGHT_WIRES_STATUS, componentId)) {
				let returnValue = getEmptyWireSlot(BOTTOM_RIGHT_WIRES_STATUS, componentId)
				if (returnValue !== -1) {
					BOTTOM_RIGHT_WIRES_STATUS = returnValue.wireStatusList
					emptyWireSlotIndex = returnValue.emptyWireSlot.pathIndex
				}
			} else {
				let reservedWireSlot = getReservedWireSlot(BOTTOM_RIGHT_WIRES_STATUS, componentId)
				if (reservedWireSlot !== -1) {
					emptyWireSlotIndex = reservedWireSlot.pathIndex
				}
			}
			if (emptyWireSlotIndex === -1) {
				path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			} else {
				path = Path().moveTo(point1.x, point1.y)
							.verticalLineTo(point1.y + (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.horizontalLineTo(point2.x)
							.verticalLineTo(point2.y)
			} 
			break
		case 'ARDUINO_TOP_RELAY':
			if (!isWireAlreadyPlaced(TOP_LEFT_WIRES_STATUS, componentId)) {
				let returnValue = getEmptyWireSlot(TOP_LEFT_WIRES_STATUS, componentId)
				if (returnValue !== -1) {
					TOP_LEFT_WIRES_STATUS = returnValue.wireStatusList
					emptyWireSlotIndex = returnValue.emptyWireSlot.pathIndex
				}
			} else {
				let reservedWireSlot = getReservedWireSlot(TOP_LEFT_WIRES_STATUS, componentId)
				if (reservedWireSlot !== -1) {
					emptyWireSlotIndex = reservedWireSlot.pathIndex
				}
			}
			if (emptyWireSlotIndex === -1) {
				path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			} else {
				path = Path().moveTo(point1.x, point1.y)
							.verticalLineTo(point1.y - (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.horizontalLineTo(ARDUINO_TOP_RELAY_REF_POINT_X + (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.verticalLineTo(point2.y)
							.horizontalLineTo(point2.x)
			} 
			break
		case 'ARDUINO_BOTTOM_RELAY':
			if (!isWireAlreadyPlaced(TOP_LEFT_WIRES_STATUS, componentId)) {
				let returnValue = getEmptyWireSlot(TOP_LEFT_WIRES_STATUS, componentId)
				if (returnValue !== -1) {
					TOP_LEFT_WIRES_STATUS = returnValue.wireStatusList
					emptyWireSlotIndex = returnValue.emptyWireSlot.pathIndex
				}
			} else {
				let reservedWireSlot = getReservedWireSlot(TOP_LEFT_WIRES_STATUS, componentId)
				if (reservedWireSlot !== -1) {
					emptyWireSlotIndex = reservedWireSlot.pathIndex
				}
			}
			if (emptyWireSlotIndex === -1) {
				path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			} else {
				path = Path().moveTo(point1.x, point1.y)
							.verticalLineTo(point1.y + (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.horizontalLineTo(ARDUINO_TOP_RELAY_REF_POINT_X + (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.verticalLineTo(point2.y)
							.horizontalLineTo(point2.x)
			}
			break
		case 'BREADBOARD_RELAY':
			path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			break
		case 'BREADBOARD_WITHIN_BLOCK':
			path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			break
		case 'BREADBOARD_BETWEEN_BLOCKS':
			if (!isWireAlreadyPlaced(BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS, componentId)) {
				let returnValue = getEmptyWireSlot(BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS, componentId)
				if (returnValue !== -1) {
					BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS = returnValue.wireStatusList
					emptyWireSlotIndex = returnValue.emptyWireSlot.pathIndex
				}
			} else {
				let reservedWireSlot = getReservedWireSlot(BREADBOARD_BETWEEN_BLOCKS_WIRES_STATUS, componentId)
				if (reservedWireSlot !== -1) {
					emptyWireSlotIndex = reservedWireSlot.pathIndex
				}
			}
			if (emptyWireSlotIndex === -1) {
				path = Path().moveTo(point1.x, point1.y)
							.lineTo(point2.x, point2.y)
			} else {
				if (slotIds[0].endsWith('U')) {
					path = Path().moveTo(point1.x, point1.y)
							.verticalLineTo(point1.y + (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.horizontalLineTo(point2.x)
							.verticalLineTo(point2.y)
				} else if (slotIds[0].endsWith('D')) {
					path = Path().moveTo(point1.x, point1.y)
							.verticalLineTo(point1.y - (emptyWireSlotIndex + 1)*GAP_BETWEEN_WIRES)
							.horizontalLineTo(point2.x)
							.verticalLineTo(point2.y)
				} else {
					path = Path().moveTo(point1.x, point1.y)
								.lineTo(point2.x, point2.y)
				}
			}
			break
		default:
			break
	}
	return path
}

export default {
	makeBreadBoardConnectionPointIds,
	getComponentSlotPositionById,
	getSlotIdByName,
	getComponentDetailsByName,
	getDistanceBetweenTwoPoints,
	getComponentsListFromCircuitData,
	getComponentDetailsById,
	getSlotNameByPosition,
	getOptionById,
	getObjectById,
	removeOtherOptionsOnBreadBoard,
	removeOtherComponentOptions,
	removeAllComponentOptions,
	highlightComponentOptionById,
	getSlotPositionXYById,
	linearSearch,
	getImagePathByColorCode,
	compareObjects,
	compareStepOptions,
	verifyWiFiAuth,
	isStepCompleted,
	isBlinkDotExists,
	isComponentExists,
	isComponentAlreadyPlaced,
	objectLength,
	generateWirePathData
}