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

import colorchooser.FeedUtil;
import colorchooser.ImageButton;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextOrigin;

/**
 * @author Rakesh Menon
 */

public class ColorPalette extends CustomNode {
    
    public var color = Color.RED;

    var x = 0.0;
    var y = 5.0;
    var width = 225.0;
    var height = 255.0;

    var timeline = Timeline {
        keyFrames: [
            KeyFrame {
                time: 0s
                values: [
                    y => - (height + 3 - x)
                ]
            },
            KeyFrame {
                time: 250ms
                values: [
                    y => 5.0 tween Interpolator.EASEOUT
                ]
            }
        ]
    };
    
    public var show = false on replace {

        if(show) {
            timeline.rate = 1;
            timeline.playFromStart();
            visible = true;
        } else {
            timeline.rate = -1;
            timeline.time = 250ms;
            timeline.play();
        }
    }

    var bgRect = Rectangle {
        width: width
        height: height
        strokeWidth: 5.0
        stroke: Color.web("#505050")
        fill: Color.web("#3E3E3E")
    }

    var innerRect = Rectangle {
        x: 5
        y: 35
        width: width - 10
        height: height - 80
        fill: Color.web("#464646")
    }

    var paletteRect = Rectangle {
        x: 20
        y: innerRect.y + 15
        width: width - 40
        height: height - innerRect.y - 75
        fill: Color.WHITE
    }
    
    var paletteWidth = (paletteRect.width - 10)/5.0;
    var paletteHeight = paletteRect.height - 10;
    
    var paletteColor : Rectangle[] = [
        Rectangle {
            id: "#ff0000"
            fill: Color.web("#ff0000")
            width: paletteWidth
            height: paletteHeight
            onMouseEntered: onMouseEntered
            onMousePressed: onMousePressed
        },
        Rectangle {
            id: "#00ff00"
            fill: Color.web("#00ff00")
            width: paletteWidth
            height: paletteHeight
            onMouseEntered: onMouseEntered
            onMousePressed: onMousePressed
        },
        Rectangle {
            id: "#0000ff"
            fill: Color.web("#0000ff")
            width: paletteWidth
            height: paletteHeight
            onMouseEntered: onMouseEntered
            onMousePressed: onMousePressed
        },
        Rectangle {
            id: "#ffffff"
            fill: Color.WHITE
            width: paletteWidth
            height: paletteHeight
            onMouseEntered: onMouseEntered
            onMousePressed: onMousePressed
        },
        Rectangle {
            id: "#000000"
            fill: Color.BLACK
            width: paletteWidth
            height: paletteHeight
            onMouseEntered: onMouseEntered
            onMousePressed: onMousePressed
        }
    ];
    
    var line1 = Line {
        startX: 5
        startY: 5
        endX: width - 5
        endY: 5
        stroke: Color.web("#393939")
    }

    var line2 = Line {
        startX: 5
        startY: height - 45
        endX: width - 5
        endY: height - 45
        stroke: Color.web("#393939")
    }

    var line3 = Line {
        startX: 5
        startY: height - 46
        endX: width - 5
        endY: height - 46
        stroke: Color.web("#414141")
    }

    var backButton : ImageButton = ImageButton {

        translateX: 5
        translateY: height - 40
        normalImage: Image { url: "{__DIR__}images/back_n.png" }
        disabledImage: Image { url: "{__DIR__}images/back_d.png" }
        enabled: bind isBackButtonEnabled(index, topTitles, newTitles)
        
        onMousePressed: function(e) {

            if(not backButton.enabled) { return; }
            
            index--;
            
            if(index >= (sizeof topTitles)) {
                var newIndex = index - (sizeof topTitles);
                setPalette(newTitles[newIndex], newColors[newIndex]);
            } else {
                setPalette(topTitles[index], topColors[index]);
            }
        }
    }

    function isBackButtonEnabled(index : Integer, topTtls: String[], newTtls: String[]) : Boolean {
        return (index > 0);
    }

    var nextButton : ImageButton = ImageButton {

        translateX: width - 38
        translateY: height - 40
        normalImage: Image { url: "{__DIR__}images/next_n.png" }
        disabledImage: Image { url: "{__DIR__}images/next_d.png" }
        enabled: bind isNextButtonEnabled(index, topTitles, newTitles)

        onMousePressed: function(e) {

            if(not nextButton.enabled) { return; }

            index++;
            
            if(index >= (sizeof topTitles)) {
                var newIndex = index - (sizeof topTitles);
                setPalette(newTitles[newIndex], newColors[newIndex]);
            } else {
                setPalette(topTitles[index], topColors[index]);
            }
        }
    }
    
    function isNextButtonEnabled(index : Integer, topTtls: String[], newTtls: String[]) : Boolean {
        return (((sizeof topTtls) + (sizeof newTtls)) > (index + 1));
    }
    
    var closeButton = ImageButton {
        translateY: 0
        translateX: width - 25
        normalImage: Image { 
            url: "{__DIR__}images/close.png"
            width: 32
            height: 32
        }
        onMousePressed: function(e) {
            show = false;
        }
        visible: ("{__PROFILE__}" != "browser")
    }
    
    var titleText : Text = Text {
        translateX: bind (width - titleText.boundsInLocal.width)/2.0
        translateY: 12
        font: Font { name: "dialog" size: 14 }
        fill: Color.WHITE
        content: "Color Chooser"
        textOrigin: TextOrigin.TOP
        clip: Rectangle {
            width: bind width - 70
            height: bind height - 10
        }
    };

    var colorRect : Rectangle = Rectangle {
        x: backButton.translateX + backButton.boundsInLocal.width + 5
        y: backButton.translateY + 5
        width: nextButton.translateX - backButton.translateX - backButton.boundsInLocal.width - 10
        height: backButton.boundsInLocal.height - 10
        fill: Color.RED
        arcWidth: 10
        arcHeight: 10
        stroke: Color.WHITE
        strokeWidth: 2.0
    }

    var colorText : Text = Text {
        translateX: bind colorRect.x + (colorRect.width - colorText.boundsInLocal.width)/2.0
        translateY: bind colorRect.y + (colorRect.height - colorText.boundsInLocal.height)/2.0 + 1.0
        font: Font { name: "dialog" size: 14 }
        fill: Color.WHITE
        content: "#ff000000"
        textOrigin: TextOrigin.TOP
        clip: Rectangle {
            width: bind width - 70
            height: bind height - 10
        }
    };
    
    var newTitles : String[];
    var newColors: String[];
    var topTitles : String[];
    var topColors: String[];
    var index = 0;
    
    init {

        var newFeedUtil = FeedUtil {
            url: "http://feeds2.feedburner.com/ColourloversCoup0Palettes/New?format=xml"
            updatePalette: updateNewPalette
        };
        newFeedUtil.start();

        var topFeedUtil = FeedUtil {
            url: "http://feeds2.feedburner.com/ColourloversCoup0Palettes/Top?format=xml"
            updatePalette: updateTopPalette
        };
        topFeedUtil.start();
    }
    
    override function create() : Node {

        clip = Rectangle {
            x: x
            y: y
            width: width
            height: height
        };
        
        var colorBox = HBox {
            translateX: paletteRect.x + 5
            translateY: paletteRect.y + 5
            content: paletteColor
        };

        Group {
            translateX: bind x
            translateY: bind y
            content: [
                bgRect, innerRect, paletteRect, 
                colorBox,  line1, line2, line3, titleText,
                backButton, nextButton, closeButton, 
                colorRect, colorText
            ]
        }
    }

    function setPalette(title : String, palette : String) {

        titleText.content = title;
        
        var colors : String[] = palette.split("/");
        var index = 0;

        for(color in colors) {
            paletteColor[index].id = "#{color}";
            paletteColor[index].fill = Color.web("#{color}");
            index++;
        }
    }
    
    public function updateNewPalette(
        ttls : String[], clrs : String[]) : Void {
        topTitles = ttls;
        topColors = clrs;
    }

    public function updateTopPalette(
        ttls : String[], clrs : String[]) : Void {
        newTitles = ttls;
        newColors = clrs;
    }

    function onMouseEntered(e : MouseEvent) : Void {
        colorRect.fill = (e.node as Rectangle).fill;
        colorText.content = e.node.id;
    }

    function onMousePressed(e : MouseEvent) : Void {
        colorRect.fill = (e.node as Rectangle).fill;
        color = Color.web("{e.node.id}");
        show = false;
    }
}