License text

/*
 * 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 stickynote;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.Object;
import javafx.io.Resource;
import javafx.io.Storage;
import javafx.lang.FX;
import javafx.scene.control.TextBox;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.Screen;
import javafx.stage.StageStyle;
import javafx.stage.Alert;

/**
 * @author Seema Gupta
 */

 /* This sample takes all the default values of how much data can be written
 per application and per file/resource. The user can modify these values as per his
 choice by using other functionality provided by storage APIs */

 /* There is a limit set for user so that he/she can't enter more than 320 characters
or 14 lines in the note */

var storage:Storage;
var res:Resource;

var count_chars:Number;
var count_lines:Number;

def max_chars = 320;
def max_lines = 14;

var width: Number = if (__PROFILE__ == "tv") then 1280
    else if ( __PROFILE__ == "mobile" ) then javafx.stage.Screen.primary.bounds.width
    else 240;
var height: Number = if (__PROFILE__ == "tv") then 720
    else if ( __PROFILE__ == "mobile" ) then javafx.stage.Screen.primary.bounds.height
    else 320;

var usrtext: String = " ";

var titlewindow: Rectangle = Rectangle {
    width: width
    height: 30
    fill: Color.DARKCYAN
    onMouseDragged: function(e) {
        if("{__PROFILE__}" != "browser") {
            widget.x = widget.x + e.dragX;
            widget.y = widget.y + e.dragY;
        }
    }
};

var textList:Text = Text {
    translateX: 20
    translateY: 70
    font:Font {
        name: "sansserif"
        size: 12
    }
    wrappingWidth: width * 0.9
    content: bind usrtext
}

var textAdd:TextBox = TextBox {
    promptText: "Enter your text here"
    width: bind width - 50
    columns: 20
    opacity: 0.5
    selectOnFocus: true
    translateX: 10
    translateY: bind (height - textAdd.boundsInLocal.height - 5)
    action:function() {
        storeText(false);
    }
}

var deleteButton = ImageButton {
    normalImage:Image { url: "{__DIR__}images/delete.png"
    }
    onMousePressed:function(e) {
        usrtext = "";
        clearStorage();
    }
}

var addButton = ImageButton {
    normalImage:Image { url: "{__DIR__}images/add.png"
    }
    onMousePressed:function(e) {
        storeText(false);
    }
    translateX: bind (width - 32)
    translateY: bind (height - textAdd.boundsInLocal.height - 5)
}

var closeButton = ImageButton{
    normalImage:Image { url: "{__DIR__}images/close.png"
    }
    onMousePressed: function(e) {
        FX.exit();
    }
}

var scene:Scene = Scene {

    var buttonBox:HBox = HBox {
        translateY: 3
        translateX: bind (width - buttonBox.boundsInLocal.width - 5)
        content: [
            deleteButton, closeButton
        ]
    };

    content: [
        titlewindow,
        textList,
        textAdd,
        addButton,
        buttonBox
    ]

    width: width
    height: height
    fill: Color.CYAN
}

var widget:Stage = Stage {
    scene: bind scene
    resizable: false
    style: StageStyle.TRANSPARENT
}

public function run () {
    if (checkStore() == true)
    loadData();
    textAdd.requestFocus();
}

public function storeText(clearold:Boolean): Void {

    var store_exists = checkStore();
    if (store_exists == true)
    loadData();
    var outp: java.io.OutputStream = res.openOutputStream(clearold);
    textAdd.commit();
    var str:String = textAdd.text;

    if(str.trim().length() == 0 ) {
        return;
    }    

    if(count_lines > max_lines ) {
        Alert.inform("Higher Limit reached for maximum number of lines on the note");
        textAdd.text= " ";
        return;
    }

    if(count_chars > max_chars ) {
        Alert.inform("Higher Limit reached for maximum number of characters on the note");
        textAdd.text= " ";
        return;
    }
    
    var newline = "\n";
    count_lines++;

    //Store data including newline character
    
    outp.write(str.getBytes());
    outp.write(newline.getBytes());    
    
    outp.close();
    loadData();
    textAdd.text = "";
    
}

public function checkStore():Boolean {

    var ret: Boolean = false;

    try {

    	/* The following code creates the storage entry for the application
        if it's not there. If the storage entry by the same name already exists
    	 it just picks up and assigns it to storage variable */

        storage = Storage {
            source: "stickynote"
        };

        res = storage.resource;
        ret = false;

    } catch (e:IOException ) {
        res = storage.resource;
        ret = true;
    }
    ret = true;
}

public function loadData():Void {

    
    /* res is a global variable and is the resource accessible by this application's storage. So
    the inputstream is being opened to res variable to read this application's existing data
     */

    var inp: InputStream = res.openInputStream();
    var currentLine: String ;
    var countoflines: Number;

    try {

        var stream = new ByteArrayOutputStream();
        var char = -1;
        while (

        (char = inp.read()) != - 1){
            if (char == 10)
            countoflines++;
            stream.write(char);
        }
        stream.close();
        var line = stream.toString();
        count_chars = line.trim().length();
        usrtext = line;
        count_lines=countoflines;

    } finally {
        inp.close();
    }
}

public function clearStorage(){
    /*  A simple clear API cleares the storage entry created above */
    storage.clear();    
}