/* 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems 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 stockquote;

import java.lang.Object;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxd.FXDLoader;
import javafx.lang.FX;
import javafx.scene.control.TextBox;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextOrigin;
import javafx.scene.transform.Transform;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import stockquote.StockQuoteUtil;

/**
 * @author JavaFX Samples Team
 */

// Application Bounds
var stageX = 300.0;
var stageY = 300.0;
def stageWidth = 240;
def stageHeight = 320;

var stageDragInitialX:Number;
var stageDragInitialY:Number;

var fxzGroup = Group {
    content: []
};

var fxdContent = FXDLoader.loadContent("{__DIR__}Stock_Quote.fxz");
var MainGroup = fxdContent.getNode("MainGroup");
var quoteBtn = fxdContent.getNode("quoteBtn");
var GetQuoteBtnText:Text =
                fxdContent.getNode("GetQuoteBtnText") as javafx.scene.text.Text;
var closeGrp = fxdContent.getNode("close_control") as javafx.scene.Group;
// Dispose Application
var closeButton:Text = fxdContent.getNode("closeButton") as javafx.scene.text.Text;

function doActionOnQuoteBtn() {
    MainGroup.onMousePressed= function(e) {
        stageDragInitialX = e.screenX - stage.x;
        stageDragInitialY = e.screenY - stage.y;
    }
     MainGroup.onMouseDragged=function(e) {
        stage.x = e.screenX - stageDragInitialX;
        stage.y = e.screenY - stageDragInitialY;
     }
    
    quoteBtn.onKeyPressed = function (e) {
        if (e.code == KeyCode.VK_ENTER  )
            validateSymbolInput();
        if (e.code == KeyCode.VK_LEFT)
           StockSymbolText.requestFocus();
    };
    quoteBtn.onMouseClicked= function(e) {
        validateSymbolInput();
    }
    
    quoteBtn.onMouseEntered = function (e) {
        GetQuoteBtnText.fill=Color.BLUE;
    }
    quoteBtn.onMouseExited = function (e) {
        GetQuoteBtnText.fill=Color.BLACK;
    }
    if("{__PROFILE__}" != "browser") {
        closeButton.onMouseClicked= function(e) {
            closeButton.fill=Color.RED;
            closeButton.stroke=Color.RED;
            closeButton.strokeWidth=1;
            javafx.lang.FX.exit();
        }
        closeButton.onMouseEntered = function (e) {
            closeButton.fill=Color.RED;
            closeButton.stroke=Color.RED;
            closeButton.strokeWidth=1;
            closeButton.fill=Color.RED;
        }
         closeButton.onMouseExited = function (e) {
            closeButton.stroke=null;
            closeButton.strokeWidth=0;
            closeButton.fill=Color.WHITE;
        }
    }
}

var defaultFont:Font = Font.font (
     "Helvetica", FontWeight.REGULAR, FontPosture.REGULAR, 12.0);

var StockSymbolText:TextBox = TextBox {
    blocksMouse: true
    translateX: 10
    translateY: stageHeight - 253
    columns: 11
    selectOnFocus: false
    text: "JAVA"
    action: function() {
        validateSymbolInput();
    }
    onKeyPressed:function(e) {
        if(e.code == KeyCode.VK_RIGHT) {
            quoteBtn.requestFocus();
            GetQuoteBtnText.fill=Color.BLUE;
        }
    }
}

function validateSymbolInput():Void {    
    var stockSymbol = StockSymbolText.rawText.trim();
    if(stockSymbol.equals("")) {
        StockSymbolText.text = "Not a valid symbol";        
    }
    else {
        util_frame.ShowQuoteData(stockSymbol, true);
        userAction = true;       
    }
}
var compNameText = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,7.852540,109.998050)]
    fill: Color.WHITE
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font: Font.font( "Helvetica", FontWeight.REGULAR, FontPosture.REGULAR, 14.00)
    smooth: false
    content: ""};

var lastTradeText = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,8.885250,133.991210)]
    fill: Color.WHITE
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    content: ""};

var imageUp = Image {
    url: "{__DIR__}Images/Up.PNG" };
var imageDown = Image {
    url: "{__DIR__}Images/Down.PNG" };

var ImgUpDown = ImageView {
    x: 55
    y: 148
    fitHeight:18
    preserveRatio : true
    image: null };

var changeFrameDataColor=Color.WHITE;
var changeTickerDataColor = Color.BLACK;

var lastChange = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,7.852540,160.038090)]
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    fill: bind changeFrameDataColor
    content: ""};

var dayRange = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,8.885250,183.030270)]
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    fill: Color.WHITE
    content: ""};

var preClose = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,7.852540,209.077150)]
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    fill: Color.WHITE
    content: ""};

var mktCap = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,8.885250,232.069336)]
    fill: Color.WHITE
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    content: ""};

var volume = Text {
    transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,7.852540,258.117188)]
    fill: Color.WHITE
    stroke: null
    textOrigin: TextOrigin.BASELINE
   font:defaultFont
    content: ""};
    
var lastTradeTime = Text {
   transforms: [Transform.affine(1.000000,0.000000,0.000000,1.000000,8.885250,281.109375)]
    fill: Color.WHITE
    stroke: null
    textOrigin: TextOrigin.BASELINE
    font:defaultFont
    content: ""};

var userAction = false;
var arrayTickerSymbols:String[];
var tickerStockData:String;
var xVal:Number=2;
var arrayTickerElement = Text {
    x: bind xVal with inverse
    y: 50
    font: Font.font( "ARIAL BOLD", FontWeight.REGULAR, FontPosture.REGULAR, 16.00)
    fill: bind changeTickerDataColor
    content: bind tickerStockData
 };
var tickerClipGrp = Group {
    clip: Rectangle {
        fill: Color.rgb(0x24,0x31,0x44,1.0)
        stroke: null
        x: 1.73
        y: 28.97
        width: 233.71
        height: 30.0
    },
}
var symbolIndex=0;
var tickerTimeline:Timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames: [
        KeyFrame {
            time: 0s
            values: xVal => stageWidth },
        KeyFrame {
            time:10s
            canSkip: true
            values: xVal => 2 tween Interpolator.LINEAR
            action: function():Void {
                if(symbolIndex >= sizeof arrayTickerSymbols)
                    symbolIndex = 0;
                util_ticker.ShowQuoteData(arrayTickerSymbols[symbolIndex],false);
                symbolIndex ++;
        } },
    ]};

function displayInFrame(result:String[]): Void {
    var changeVal = {result[4]} ;
    var  changeValInPrecntage = {result[11]};
    if(changeVal.startsWith("-")) {
        changeFrameDataColor=Color.rgb(0xff,0x4e,0x0,1.0);
        ImgUpDown.image =  imageDown;
        changeVal = changeVal.substring(1);
        changeValInPrecntage = changeValInPrecntage.substring(1);
    }
    else if(changeVal.startsWith("+")) {
        changeFrameDataColor=Color.rgb(128,255,0);
        ImgUpDown.image =  imageUp;
        changeVal = changeVal.substring(1);
        changeValInPrecntage = changeValInPrecntage.substring(1);
    }
    else {
        ImgUpDown.image =  null;
        changeFrameDataColor=Color.WHITE;
    }
    compNameText.content="{result[15]}";
    preClose.content = "Previous Close: {result[5]}";
    lastTradeText.content="Last Trade: {result[1]} ";
    lastChange.content =  "Change:    {changeVal} ({changeValInPrecntage})";
    dayRange.content = "Today's Range: {result[7]} - {result[6]}";
    mktCap.content = "Market Cap: {result[9]}";
    volume.content = "Volume: {result[7]}";
    lastTradeTime.content = "Date & Time: {result[2]} {result[3]}";
}

var symbolDisplayOnFrame:String;
var isVaildSymbol = false;
public function setFrameData(result:String[]): Void{
    if(userAction) {
        if("{result[1]}".equals("0.00") and
            "{result[4]}".equals("N/A") and
            "{result[5]}".equals("N/A") and
        "{result[6]}".equals("N/A") ) {
            StockSymbolText.text="Not a valid symbol";
            isVaildSymbol = false;
            return;
        }
        else {
            isVaildSymbol = true;
        }
   }
    if((not util_frame.httpRequestError) and (isVaildSymbol)) {
        symbolDisplayOnFrame={result[0]};
        displayInFrame(result);
        addArrayTickerSymbols(result[0],result);
        userAction = false;        
    }
    if (not (symbolDisplayOnFrame.equals(result[0]))) {
        //Do nothing ignore this case...
    }
    else {
        displayInFrame(result);
    }
}
function addArrayTickerSymbols(newSymbol:String,result:String[]):Void {
    if( sizeof arrayTickerSymbols == 0) {
        insert newSymbol into arrayTickerSymbols;
        println("adding first symbol into arrayTickerSymbols: {newSymbol}");
        setTickerDataColor(result[4]);
        tickerStockData = "{result[0]}: {result[1]} {result[4]} ({result[11]})";
        insert tickerStockData into arrayTickerSymbolsData;
        return;
    }
    var symbolExist=false;
    for(symbol in arrayTickerSymbols ) {
        if(newSymbol.equals(symbol))
            symbolExist=true;
    }
    if(not symbolExist) {
        insert newSymbol into arrayTickerSymbols;
        setTickerDataColor(result[4]);
        tickerStockData = "{result[0]}: {result[1]} {result[4]} ({result[11]})";
        insert tickerStockData into arrayTickerSymbolsData;
    }
}
function setTickerDataColor(lastChange:String) {
    if(lastChange.startsWith("-")) {
        changeTickerDataColor = Color.rgb(0xff,0x4e,0x0,1.0);
    }
    else  if(lastChange.startsWith("+")) {
        changeTickerDataColor = Color.rgb(128,255,0,1.0);
    }
    else {
        changeTickerDataColor = Color.WHITE;
    }
}
var arrayTickerSymbolsData:String[];
public function showTicker(result:String[],symbol:String): Void {    
    for(i in [0.. sizeof arrayTickerSymbolsData]) {
        if(arrayTickerSymbolsData[i].indexOf(symbol) != -1) {
            setTickerDataColor(result[4]);
            arrayTickerSymbolsData[i] =
                "{result[0]}: {result[1]} {result[4]} ({result[11]})";
            tickerStockData = arrayTickerSymbolsData[i];            
        }
    }    
}

var grpTicker:Group;
// Application User Interface
def stage = Stage {
    resizable: false
    x: bind stageX with inverse
    y: bind stageY with inverse
    width: stageWidth
    height: stageHeight
    visible: true
    style: StageStyle.TRANSPARENT
    scene: Scene {
        fill: Color.TRANSPARENT
        content: [
            Group {
                content: [
                fxzGroup,StockSymbolText,ImgUpDown,lastTradeText,compNameText,
                lastTradeTime,lastChange,mktCap, volume, dayRange, preClose
                ]
                clip: Rectangle {
                    width:stageWidth
                    height:stageHeight
                    arcWidth:20
                    arcHeight:20
                }
            },
            grpTicker = Group {
                content: [{arrayTickerElement}] }
        ]        
    }
}

var util_frame:StockQuoteUtil;
var util_ticker:StockQuoteUtil;
function run() {
    insert MainGroup into fxzGroup.content; // inserts the fxd content into the group
    
    if("{__PROFILE__}" == "browser") {
        closeGrp.visible = false;
    }
    doActionOnQuoteBtn();
    
    // Reset TextBox bounds for Mobile
    if(FX.getProperty("javafx.me.profiles") != null) {
        stageX = 0.0;
        stageY = 0.0;
    }
    util_frame = new StockQuoteUtil();
    util_ticker = new StockQuoteUtil();
    userAction = true;
    util_frame.ShowQuoteData("JAVA",true);
    tickerTimeline.play();
}