/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Oracle Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package whiteout;
import javafx.animation.Timeline;
import javafx.animation.Interpolator;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import java.util.Random;
class Light extends Group {
public-init var env: Env;
var gx: Integer;
var gy: Integer;
var selected: Boolean = false;
var row: Row;
var model: Model;
def size1 = env.gameButtonSize;
var strokeAlpha = 0.0;
def fade = Timeline {
keyFrames: [
at(0s) { strokeAlpha => 0.0 tween Interpolator.LINEAR },
at(0.5s) { strokeAlpha => 1.0 tween Interpolator.LINEAR }
]
};
var view: Rectangle = Rectangle {
fill: env.blueGrad
width: size1
height: size1
arcWidth: 10
arcHeight: 10
stroke: bind Color {
red: 0.9
green: 0.9
blue: 0.9
opacity: strokeAlpha
}
strokeWidth: env.gameButtonStrokeWidth
onMouseEntered: function(e) {
if (not model.finished) {
fade.rate = 10.0;
fade.play();
}
}
onMouseExited: function(e) {
fade.rate = -10.0;
fade.play();
}
onMousePressed: function(e) {
if (not model.finished) {
toggle();
}
if (model.finished) {
fade.rate = -10.0;
fade.play();
}
}
};
init {
content = [
Rectangle {
fill: Color.rgb(0x0,0x0,0x0,.5)
translateX: 2
translateY: 2
width: size1
height: size1
arcWidth: 10
arcHeight: 10
},
view
];
translateX = env.gameButtonGap + gx * (size1 + env.gameButtonGap);
translateY = env.topMargin + gy * (size1 + env.gameButtonGap);
}
function isSelected() : Boolean {
return selected;
}
function setSelected(t: Boolean ) : Void {
if (not selected == t) {
selected = t;
view.fill = if (selected) Color.WHITE else env.blueGrad;
}
}
function triggerAdjacent() {
if (sizeof row.lights > gx + 1) {
row.lights[gx + 1].flip();
}
if (0 <= gx - 1) {
row.lights[gx - 1].flip();
}
if (sizeof model.rows > gy + 1) {
row.model.rows[gy + 1].lights[gx].flip();
}
if (0 <= gy - 1) {
row.model.rows[gy - 1].lights[gx].flip();
}
}
function toggle() : Void {
setSelected(not selected);
triggerAdjacent();
model.moveCount++;
model.checkFinished();
}
function flip() {
setSelected(not selected);
}
}
class Row extends Group {
var lights: Light[];
var model: Model;
}
public class Model extends Group {
public-init var env: Env;
public var rows : Row[];
public var moveCount: Integer;
public var finished: Boolean;
public var level = 0;
def generator = new Random();
init {
for (i in [0..env.nButtons - 1]) {
def row = Row {model: this};
for (j in [0..env.nButtons - 1]) {
def light = Light{env: env, gx: j, gy: i, row: row, model: this};
insert light into row.lights;
}
insert row into rows;
row.content = row.lights;
}
content = rows;
finished = true;
randomize();
}
public function reset() {
clear();
randomize();
}
public function clear() {
for (aRow in rows, aLight in aRow.lights) {
aLight.setSelected(false);
}
finished = true;
}
public function randomize() {
while(finished) {
for (i in [0..(level + 1)]) {
rows[generator.nextInt(4)].lights[generator.nextInt(4)].toggle();
}
checkFinished();
}
moveCount = 0;
}
function checkFinished() {
for (aRow in rows, aLight in aRow.lights) {
if (aLight.selected) {
finished = false;
return
}
}
finished = true;
}
}