File indexing completed on 2024-04-28 15:07:48

0001 /* GCompris - digital_electricity.js
0002  *
0003  * SPDX-FileCopyrightText: 2016 Pulkit Gupta <pulkitnsit@gmail.com>
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
0008  *   Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
0009  *   Timothée Giet <animtim@gmail.com> (mouse drag refactoring)
0010  *
0011  *   SPDX-License-Identifier: GPL-3.0-or-later
0012  */
0013 .pragma library
0014 .import QtQuick 2.12 as Quick
0015 .import "qrc:/gcompris/src/core/core.js" as Core
0016 
0017 var numberOfLevel
0018 var items
0019 var url = "qrc:/gcompris/src/activities/digital_electricity/resource/"
0020 var toolDelete
0021 var selectedIndex
0022 var animationInProgress
0023 var selectedTerminal
0024 var deletedIndex = []
0025 var components = []
0026 var connected = []
0027 var determiningComponents = []
0028 var processingAnswer
0029 
0030 var currentZoom
0031 var maxZoom = 0.375
0032 var minZoom = 0.125
0033 var defaultZoom = 0.25
0034 var zoomStep = 0.0625
0035 
0036 var direction = {
0037     LEFT: -1,
0038     RIGHT: 1,
0039     UP: -2,
0040     DOWN: 2
0041 }
0042 
0043 var viewPort = {
0044     leftExtreme: 0,
0045     rightExtreme: 1,
0046     topExtreme: 0,
0047     bottomExtreme: 1,
0048     leftEdge: 0,
0049     topEdge: 0
0050 }
0051 
0052 function start(items_) {
0053     items = items_
0054     numberOfLevel = items.tutorialDataset.tutorialLevels.length
0055     items.currentLevel = Core.getInitialLevel(numberOfLevel)
0056     initLevel()
0057 }
0058 
0059 function stop() {
0060     for(var i = 0 ; i < components.length ; ++i) {
0061         var j
0062         for(j = 0 ; j < deletedIndex.length ; ++j) {
0063             if(deletedIndex[j] == i)
0064                 break
0065         }
0066         if(j == deletedIndex.length)
0067             removeComponent(i)
0068     }
0069 }
0070 
0071 function initLevel() {
0072 
0073     items.availablePieces.view.currentDisplayedGroup = 0
0074     items.availablePieces.view.previousNavigation = 1
0075     items.availablePieces.view.nextNavigation = 1
0076     deletedIndex = []
0077     components = []
0078     connected = []
0079     determiningComponents = []
0080     animationInProgress = false
0081     disableToolDelete()
0082     deselect()
0083     updateToolTip("")
0084     items.availablePieces.hideToolbar()
0085 
0086     currentZoom = defaultZoom
0087     items.availablePieces.zoomInBtn.state = "canZoomIn"
0088     items.availablePieces.zoomOutBtn.state = "canZoomOut"
0089     viewPort.leftEdge = 0
0090     viewPort.topEdge = 0
0091     items.playArea.x = items.mousePan.drag.maximumX
0092     items.playArea.y = items.mousePan.drag.maximumY
0093 
0094     if (!items.isTutorialMode) {
0095         items.tutorialInstruction.index = -1
0096         loadFreeMode()
0097     } else {
0098         // load tutorial levels from dataset
0099         processingAnswer = false
0100         var levelProperties = items.tutorialDataset.tutorialLevels[items.currentLevel]
0101 
0102         for (var i = 0; i < levelProperties.inputComponentList.length; i++) {
0103             var currentInputComponent = levelProperties.inputComponentList[i]
0104             items.availablePieces.model.append( {
0105                "imgName": currentInputComponent.imageName,
0106                "componentSrc": currentInputComponent.componentSource,
0107                "imgWidth": currentInputComponent.width,
0108                "imgHeight": currentInputComponent.height,
0109                "toolTipText": currentInputComponent.toolTipText
0110             })
0111         }
0112 
0113         for (var i = 0; i < levelProperties.playAreaComponentList.length; i++) {
0114             var index = components.length
0115             var currentPlayAreaComponent = levelProperties.playAreaComponentList[i]
0116             var staticElectricalComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" + currentPlayAreaComponent.componentSource)
0117             components[index] = staticElectricalComponent.createObject(
0118                         items.playArea, {
0119                           "index": index,
0120                           "posX": levelProperties.playAreaComponentPositionX[i] * currentZoom,
0121                           "posY": levelProperties.playAreaComponentPositionY[i] * currentZoom,
0122                           "imgSrc": currentPlayAreaComponent.imageName,
0123                           "toolTipTxt": currentPlayAreaComponent.toolTipText,
0124                           "imgWidth": currentPlayAreaComponent.width * currentZoom,
0125                           "imgHeight": currentPlayAreaComponent.height * currentZoom,
0126                           "destructible": false
0127                         });
0128         }
0129 
0130         var _determiningComponentsIndex = levelProperties.determiningComponentsIndex
0131         for (var i = 0; i < _determiningComponentsIndex.length; i++) {
0132             determiningComponents[determiningComponents.length] = components[_determiningComponentsIndex[i]]
0133         }
0134 
0135         // creating wires
0136         for (i = 0; i < levelProperties.wires.length; i++) {
0137             var terminal_number = levelProperties.wires[i][1]
0138             var outTerminal = components[levelProperties.wires[i][0]].outputTerminals.itemAt(terminal_number)
0139 
0140             terminal_number = levelProperties.wires[i][3]
0141             var inTerminal = components[levelProperties.wires[i][2]].inputTerminals.itemAt(terminal_number)
0142 
0143             createWire(inTerminal, outTerminal, false)
0144         }
0145 
0146         if (levelProperties.introMessage.length != 0) {
0147             items.tutorialInstruction.index = 0
0148             items.tutorialInstruction.intro = levelProperties.introMessage
0149         } else {
0150             items.tutorialInstruction.index = -1
0151         }
0152     }
0153 }
0154 
0155 function loadFreeMode() {
0156     var componentList = items.tutorialDataset.componentList
0157     for (var i = 0; i < componentList.length; i++) {
0158         items.availablePieces.model.append( {
0159             "imgName": componentList[i].imageName,
0160             "componentSrc": componentList[i].componentSource,
0161             "imgWidth": componentList[i].width,
0162             "imgHeight": componentList[i].height,
0163             "toolTipText": componentList[i].toolTipText
0164         })
0165     }
0166 }
0167 
0168 function checkAnswer() {
0169     if (processingAnswer)
0170         return
0171 
0172     processingAnswer = true
0173     var problemType = items.tutorialDataset.tutorialLevels[items.currentLevel].type
0174     var levelProperties = items.tutorialDataset.tutorialLevels[items.currentLevel]
0175 
0176     if (problemType == items.tutorialDataset.problemType.lightTheBulb) {
0177         if (determiningComponents[0].inputTerminals.itemAt(0).value == 1) {
0178             items.bonus.good('tux')
0179         } else {
0180             items.bonus.bad('tux', items.bonus.checkAnswer)
0181             processingAnswer = false
0182         }
0183     } else if (problemType == items.tutorialDataset.problemType.equation1Variable) {
0184         var switch1 = determiningComponents[0]
0185         var digitalLight = determiningComponents[1]
0186         var switch1InitialState = switch1.imgSrc
0187 
0188         for (var A = 0; A <= 1; A++) {
0189             switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
0190 
0191             updateComponent(switch1.index)
0192 
0193             var operationResult = !A
0194 
0195             if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
0196                 switch1.imgSrc = switch1InitialState
0197                 updateComponent(switch1.index)
0198                 items.bonus.bad('tux', items.bonus.checkAnswer)
0199                 processingAnswer = false
0200                 return
0201             }
0202         }
0203         items.bonus.good('tux')
0204     } else if (problemType == items.tutorialDataset.problemType.equation2Variables) {
0205         var digitalLight = determiningComponents[determiningComponents.length - 1]
0206         var switch1 = determiningComponents[0]
0207         var switch2 = determiningComponents[1]
0208 
0209         var switch1InitialState = switch1.imgSrc
0210         var switch2InitialState = switch2.imgSrc
0211 
0212         for (var A = 0; A <= 1; A++) {
0213             for (var B = 0; B <= 1; B++) {
0214                 switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
0215                 switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg"
0216 
0217                 updateComponent(switch1.index)
0218                 updateComponent(switch2.index)
0219 
0220                 var operationResult = levelProperties.result(A, B)
0221 
0222                 if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
0223                     switch1.imgSrc = switch1InitialState
0224                     switch2.imgSrc = switch2InitialState
0225                     updateComponent(switch1.index)
0226                     updateComponent(switch2.index)
0227                     items.bonus.bad('tux', items.bonus.checkAnswer)
0228                     processingAnswer = false
0229                     return
0230                 }
0231             }
0232         }
0233         items.bonus.good('tux')
0234     } else if (problemType == items.tutorialDataset.problemType.equation3Variables) {
0235         var switch1 = determiningComponents[0]
0236         var switch2 = determiningComponents[1]
0237         var switch3 = determiningComponents[2]
0238 
0239         var digitalLight = determiningComponents[3]
0240 
0241         var switch1InitialState = switch1.imgSrc
0242         var switch2InitialState = switch2.imgSrc
0243         var switch3InitialState = switch3.imgSrc
0244 
0245         for (var A = 0; A <= 1; A++) {
0246             for (var B = 0; B <= 1; B++) {
0247                 for (var C = 0; C <= 1; C++) {
0248                     switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
0249                     switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg"
0250                     switch3.imgSrc = C == 1 ? "switchOn.svg" : "switchOff.svg"
0251 
0252                     updateComponent(switch1.index)
0253                     updateComponent(switch2.index)
0254                     updateComponent(switch3.index)
0255 
0256                     var operationResult = levelProperties.result(A, B, C)
0257 
0258                     if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
0259                         switch1.imgSrc = switch1InitialState
0260                         switch2.imgSrc = switch2InitialState
0261                         switch3.imgSrc = switch3InitialState
0262                         updateComponent(switch1.index)
0263                         updateComponent(switch2.index)
0264                         updateComponent(switch3.index)
0265                         processingAnswer = false
0266                         items.bonus.bad('tux', items.bonus.checkAnswer)
0267                         return
0268                     }
0269                 }
0270             }
0271         }
0272         items.bonus.good('tux')
0273     } else if (problemType == items.tutorialDataset.problemType.others) {
0274         if (items.currentLevel == 10) {
0275             var switch1 = determiningComponents[0]
0276             var digitalLight = determiningComponents[1]
0277             var switch1InitialState = switch1.imgSrc
0278 
0279             for (var A = 0; A <= 1; A++) {
0280                 switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
0281 
0282                     updateComponent(switch1.index)
0283 
0284                     var operationResult = A
0285 
0286                     if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
0287                         switch1.imgSrc = switch1InitialState
0288                             updateComponent(switch1.index)
0289                             items.bonus.bad('tux', items.bonus.checkAnswer)
0290                             processingAnswer = false
0291                             return
0292                     }
0293             }
0294             items.bonus.good('tux')
0295         }
0296         if (items.currentLevel == 25) {
0297             var bcdToSevenSegment = determiningComponents[0]
0298 
0299             var decimalValue =
0300                     bcdToSevenSegment.inputTerminals.itemAt(3).value +
0301                     (bcdToSevenSegment.inputTerminals.itemAt(2).value * 2) +
0302                     (bcdToSevenSegment.inputTerminals.itemAt(1).value * 4) +
0303                     (bcdToSevenSegment.inputTerminals.itemAt(0).value * 8)
0304 
0305             if (decimalValue == 6) {
0306                 items.bonus.good('tux')
0307                 return
0308             }
0309             items.bonus.bad('tux', items.bonus.checkAnswer)
0310             processingAnswer = false
0311             return
0312         } else if (items.currentLevel == 26) {
0313             var bcdCounter = determiningComponents[0]
0314 
0315             var bcdOutput =
0316                     bcdCounter.outputTerminals.itemAt(3).value +
0317                     bcdCounter.outputTerminals.itemAt(2).value * 2 +
0318                     bcdCounter.outputTerminals.itemAt(1).value * 4 +
0319                     bcdCounter.outputTerminals.itemAt(0).value * 8
0320 
0321             var bcdToSevenSegment = determiningComponents[1]
0322             var decimalValue =
0323                     bcdToSevenSegment.inputTerminals.itemAt(3).value +
0324                     (bcdToSevenSegment.inputTerminals.itemAt(2).value * 2) +
0325                     (bcdToSevenSegment.inputTerminals.itemAt(1).value * 4) +
0326                     (bcdToSevenSegment.inputTerminals.itemAt(0).value * 8)
0327 
0328             if (bcdCounter.inputTerminals.itemAt(0).wires.length == 0 ||
0329                     bcdCounter.outputTerminals.itemAt(0).wires.length == 0 ||
0330                     bcdCounter.outputTerminals.itemAt(1).wires.length == 0 ||
0331                     bcdCounter.outputTerminals.itemAt(2).wires.length == 0 ||
0332                     bcdCounter.outputTerminals.itemAt(3).wires.length == 0) {
0333                 items.bonus.bad('tux')
0334                 processingAnswer = false
0335                 return
0336             }
0337             if ((bcdOutput == decimalValue) && (bcdCounter.inputTerminals.itemAt(0).wires.length != 0) ) {
0338                 items.bonus.good('tux')
0339                 return
0340             }
0341             items.bonus.bad('tux', items.bonus.checkAnswer)
0342             processingAnswer = false
0343         }
0344     }
0345 }
0346 
0347 function zoomIn() {
0348     var previousZoom = currentZoom
0349     currentZoom += zoomStep
0350     if (currentZoom > maxZoom)
0351         currentZoom = maxZoom
0352     var zoomRatio = currentZoom / previousZoom
0353     updateComponentDimension(zoomRatio)
0354 
0355     if (currentZoom == maxZoom) {
0356         items.availablePieces.zoomInBtn.state = "cannotZoomIn"
0357     } else {
0358         items.availablePieces.zoomInBtn.state = "canZoomIn"
0359     }
0360     items.availablePieces.zoomOutBtn.state = "canZoomOut"
0361 
0362     if (items.zoomLvl < 0.5) {
0363         items.zoomLvl += 0.125
0364     }
0365 }
0366 
0367 function zoomOut() {
0368     var previousZoom = currentZoom
0369     currentZoom -= zoomStep
0370     if (currentZoom < minZoom)
0371         currentZoom = minZoom
0372     var zoomRatio = currentZoom / previousZoom
0373     updateComponentDimension(zoomRatio)
0374 
0375     if (currentZoom == minZoom) {
0376         items.availablePieces.zoomOutBtn.state = "cannotZoomOut"
0377     } else {
0378         items.availablePieces.zoomOutBtn.state = "canZoomOut"
0379     }
0380     items.availablePieces.zoomInBtn.state = "canZoomIn"
0381 
0382     if (items.zoomLvl > 0) {
0383         items.zoomLvl -= 0.125
0384     }
0385 }
0386 
0387 function updateComponentDimension(zoomRatio) {
0388     for (var i = 0; i < components.length; i++) {
0389         components[i].posX *= zoomRatio
0390         components[i].posY *= zoomRatio
0391         components[i].imgWidth *= zoomRatio
0392         components[i].imgHeight *= zoomRatio
0393     }
0394 }
0395 
0396 function nextLevel() {
0397     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0398     reset();
0399 }
0400 
0401 function previousLevel() {
0402     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0403     reset();
0404 }
0405 
0406 function reset() {
0407     stop()
0408     items.availablePieces.model.clear()
0409     initLevel()
0410 }
0411 
0412 // Creates component from ListWidget to the drawing board area
0413 function createComponent(x, y, componentIndex) {
0414     x = x / items.playArea.width
0415     y = y / items.playArea.height
0416 
0417     var index
0418     if(deletedIndex.length > 0) {
0419         index = deletedIndex[deletedIndex.length - 1]
0420         deletedIndex.pop()
0421     }
0422     else
0423         index = components.length
0424 
0425     var component = items.availablePieces.repeater.itemAt(componentIndex)
0426     var electricComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" +
0427                                                component.source)
0428 
0429     //console.log("Error loading component:", electricComponent.errorString())
0430     components[index] = electricComponent.createObject(
0431                         items.playArea, {
0432                             "index": index,
0433                             "posX": x,
0434                             "posY": y,
0435                             "imgSrc": component.imageName,
0436                             "toolTipTxt": component.toolTipTxt,
0437                             "imgWidth": component.imageWidth * currentZoom,
0438                             "imgHeight": component.imageHeight * currentZoom,
0439                             "destructible": true
0440                         });
0441 
0442     deselect()
0443     componentSelected(index)
0444     updateComponent(index)
0445 }
0446 
0447 /* Creates wire between two terminals. Condition for creation of wire is that an input terminal
0448  * can only be connected to 1 wire, output terminals can be connected by any number of wires, and
0449  * an input terminal can be connected with an output terminal only. 'connected' variable is used
0450  * to make sure that an input is connected by only 1 wire.
0451 */
0452 function terminalPointSelected(terminal) {
0453     if(selectedTerminal == -1 || selectedTerminal == terminal)
0454         selectedTerminal = terminal
0455     else if((selectedTerminal.type != terminal.type) && (selectedTerminal.parent != terminal.parent)) {
0456         var inTerminal = terminal.type == "In" ? terminal : selectedTerminal
0457         var outTerminal = terminal.type == "Out" ? terminal : selectedTerminal
0458         if(connected[inTerminal] == undefined || connected[inTerminal] == -1) {
0459             createWire(inTerminal, outTerminal, true)
0460         }
0461         deselect()
0462     }
0463     else {
0464         deselect()
0465         selectedTerminal = terminal
0466         terminal.selected = true
0467     }
0468     disableToolDelete();
0469 }
0470 
0471 function createWire(inTerminal, outTerminal, destructible) {
0472     var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml")
0473     var wire = wireComponent.createObject(
0474                items.playArea, {
0475                     "from": outTerminal,
0476                     "to": inTerminal,
0477                     "destructible": destructible
0478                 });
0479     inTerminal.value = outTerminal.value
0480     inTerminal.wires.push(wire)
0481     outTerminal.wires.push(wire)
0482     updateWires(inTerminal.parent.index)
0483     updateWires(outTerminal.parent.index)
0484     updateComponent(inTerminal.parent.index)
0485     connected[inTerminal] = outTerminal
0486 }
0487 
0488 /* Updates the output of the component. 'wireVisited' is used to update the value of
0489  * each wire once which will avoid updating the outputs of components in an infinite loop.
0490 */
0491 function updateComponent(index) {
0492     var wireVisited = []
0493     components[index].updateOutput(wireVisited)
0494 }
0495 
0496 /* Updates the orientation of the wire. It is called whenever a new wire is created or
0497  * an object is rotated.
0498 */
0499 function updateWires(index) {
0500     var component = components[index]
0501     if(component == undefined || component.noOfInputs == undefined || component.noOfOutputs == undefined)
0502         return
0503 
0504     var rotatedAngle = component.initialAngle * Math.PI / 180
0505     for(var i = 0 ; i < component.noOfInputs ; ++i) {
0506         var terminal = component.inputTerminals.itemAt(i)
0507         if(terminal.wires.length != 0) {
0508             var wire = terminal.wires[0]
0509             var otherAngle = wire.from.parent.initialAngle * Math.PI / 180
0510             var x = wire.from.xCenterFromComponent
0511             var y = wire.from.yCenterFromComponent
0512             var x1 = wire.from.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle)
0513             var y1 = wire.from.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle)
0514 
0515             x = terminal.xCenterFromComponent
0516             y = terminal.yCenterFromComponent
0517             var x2 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle)
0518             var y2 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle)
0519 
0520             var width = Math.pow((Math.pow(x1 - x2, 2) +  Math.pow(y1 - y2, 2)),0.5) + 2
0521             var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1))
0522             if(x2 - x1 < 0) angle = angle - 180
0523             wire.x = x1
0524             wire.y = y1 - wire.height / 2
0525             wire.width = width
0526             wire.rotation = angle
0527         }
0528     }
0529     for(var i = 0 ; i < component.noOfOutputs ; ++i) {
0530         var terminal = component.outputTerminals.itemAt(i)
0531         for(var j = 0 ; j < terminal.wires.length ; ++j) {
0532             var x = terminal.xCenterFromComponent
0533             var y = terminal.yCenterFromComponent
0534             var x1 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle)
0535             var y1 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle)
0536 
0537             var wire = terminal.wires[j]
0538             var otherAngle = wire.to.parent.initialAngle * Math.PI / 180
0539             x = wire.to.xCenterFromComponent
0540             y = wire.to.yCenterFromComponent
0541             var x2 = wire.to.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle)
0542             var y2 = wire.to.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle)
0543 
0544             var width = Math.pow((Math.pow(x1 - x2, 2) +  Math.pow(y1 - y2, 2)),0.5) + 2
0545             var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1))
0546             if(x2 - x1 < 0)
0547                 angle = angle - 180
0548             wire.x = x1
0549             wire.y = y1
0550             wire.width = width
0551             wire.rotation = angle
0552         }
0553     }
0554 }
0555 
0556 function disableToolDelete() {
0557     if(toolDelete == true) {
0558         toolDelete = false;
0559         items.availablePieces.toolDelete.state = "notSelected";
0560     }
0561 }
0562 
0563 function deselect() {
0564     items.availablePieces.rotateLeft.state = "canNotBeSelected"
0565     items.availablePieces.rotateRight.state = "canNotBeSelected"
0566     items.availablePieces.info.state = "canNotBeSelected"
0567     items.infoTxt.visible = false
0568     selectedIndex = -1
0569     selectedTerminal = -1
0570     for(var i = 0 ; i < components.length ; ++i) {
0571         var component = components[i]
0572         for(var j = 0 ; j < component.noOfInputs ; ++j)
0573             component.inputTerminals.itemAt(j).selected = false
0574         for(var j = 0 ; j < component.noOfOutputs ; ++j)
0575             component.outputTerminals.itemAt(j).selected = false
0576     }
0577 }
0578 
0579 function removeComponent(index) {
0580     var component = components[index]
0581     for(var i = 0 ; i < component.noOfInputs ; ++i) {
0582         var terminal = component.inputTerminals.itemAt(i)
0583         if(terminal.wires.length != 0) // Input Terminal can have only 1 wire
0584             removeWire(terminal.wires[0])
0585     }
0586     for(var i = 0 ; i < component.noOfOutputs ; ++i) {
0587         var terminal = component.outputTerminals.itemAt(i)
0588         while (terminal.wires.length != 0) {
0589             removeWire(terminal.wires[0]) // Output Terminal can have more than 1 wire
0590         }
0591     }
0592     components[index].destroy()
0593     deletedIndex.push(index)
0594     deselect()
0595 }
0596 
0597 function removeWire(wire) {
0598     var inTerminal = wire.to
0599     var outTerminal = wire.from
0600 
0601     var removeIndex = inTerminal.wires.indexOf(wire)
0602     inTerminal.wires.splice(removeIndex, 1)
0603     removeIndex = outTerminal.wires.indexOf(wire)
0604     outTerminal.wires.splice(removeIndex, 1)
0605     connected[wire.to] = -1
0606 
0607     inTerminal.value = 0
0608     wire.destroy()
0609     updateComponent(inTerminal.parent.index)
0610     deselect()
0611 }
0612 
0613 function componentSelected(index) {
0614     selectedIndex = index
0615     items.availablePieces.rotateLeft.state = "canBeSelected"
0616     items.availablePieces.rotateRight.state = "canBeSelected"
0617     items.availablePieces.info.state = "canBeSelected"
0618 }
0619 
0620 function rotateLeft() {
0621     components[selectedIndex].rotationAngle = -2
0622     components[selectedIndex].rotateComponent.start()
0623 }
0624 
0625 function rotateRight() {
0626     components[selectedIndex].rotationAngle = 2
0627     components[selectedIndex].rotateComponent.start()
0628 }
0629 
0630 function displayInfo() {
0631     var component = components[selectedIndex]
0632     var componentTruthTable = component.truthTable
0633     deselect()
0634     items.infoTxt.visible = true
0635     items.infoTxt.text = component.information
0636 
0637     if(component.infoImageSrc != undefined) {
0638         items.infoImage.imgVisible = true
0639         items.infoImage.source = url + component.infoImageSrc
0640     }
0641     else {
0642         items.infoImage.imgVisible = false
0643         items.infoImage.source = ""
0644     }
0645 
0646     if(componentTruthTable.length == 0)
0647         items.displayTruthTable = false
0648     else {
0649         items.displayTruthTable = true
0650         var truthTable = items.truthTablesModel
0651         truthTable.clear()
0652         truthTable.rows = componentTruthTable.length
0653         truthTable.columns = componentTruthTable[0].length
0654         truthTable.inputs = component.noOfInputs
0655         truthTable.outputs = component.noOfOutputs
0656         for(var i = 0 ; i < componentTruthTable.length ; ++i)
0657             for(var j = 0 ; j < componentTruthTable[i].length ; ++j)
0658                 truthTable.append({'value': componentTruthTable[i][j]})
0659     }
0660 }
0661 
0662 function updateToolTip(toolTipTxt) {
0663     items.toolTip.show(toolTipTxt)
0664 }