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

import java.lang.Exception;
import java.lang.Object;
import javafx.io.http.HttpRequest;
import javafx.io.http.URLConverter;
import javafx.lang.FX;
import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.Group;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import mosaic.ImageButton;
import mosaic.Photo;
import mosaic.PhotoPullParser;
import mosaic.ThumbImage;

/**
 * @author Rakesh Menon
 */

var stageDragInitialX:Number;
var stageDragInitialY:Number;

// Tag to search
var tag = "garden";

def apiKey = "c383a2f8d22a3e3788568cb1c64386fc";
def license = "&license=Attribution-NonCommercial-ShareAlike";
def count = "30";

public var width : Number = bind scene.width;
public var height : Number = bind scene.height;

var urlConverter = URLConverter{};

var request: HttpRequest;

function loadImageMetadata() : Void {
    
    for(node in thumbGroup.content) {
        (node as ThumbImage).cancel();
    }
    
    println("Searching for tag - \"{tag}\"");
    var httpRequestError: Boolean = false;
    
    // Submit HttpRequest
    request = HttpRequest {

        location: "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={apiKey}"
          "&sort=date-posted-desc&tags={tag}&per_page={count}{license}";
        
        method: HttpRequest.GET

        onException: function(exception: Exception) {
            exception.printStackTrace();
            println("Error - {exception}");
            httpRequestError = true;
        }

        onResponseCode: function(responseCode:Integer) {
            if (responseCode != 200) {
                println("failed, response: {responseCode} {request.responseMessage}");
            }
        }

        onInput: function(input: java.io.InputStream) {
            
            try {

                var parser = PhotoPullParser {
                    onDone: updateImages
                };
                parser.parse(input);

                if(parser.errorMessage.length() > 0) {
                    println("Error - {parser.errorMessage}");
                    httpRequestError = true;
                }

             } finally {
                input.close();
             }
        }

        onDone: function() {
            tagTextBox.disable = false;
            searchButton.disable = false;
        }
    }

    request.start();
}

function search() : Void {

    tagTextBox.commit();
    tag = urlConverter.encodeURL(tagTextBox.text);
    loadImageMetadata();
    
    tagTextBox.disable = true;
    searchButton.disable = true;
}

var thumbGroup = Group { };
function updateImages(photos : Photo[]) {

    delete thumbGroup.content;
    if(photos == null) {
        return;
    }
    
    for(photo in photos) {
        insert ThumbImage {
            url: "http://farm{photo.farm}.static.flickr.com/{photo.server}/{photo.id}_{photo.secret}";
        } into thumbGroup.content;
    }
}

var bottomRect : Rectangle = Rectangle {
    y: bind (height - bottomRect.height)
    height: bind (tagTextBox.boundsInLocal.height + 15)
    width: bind width
    fill: LinearGradient {
        startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
        proportional: true
        stops: [
            Stop { offset: 0.0 color: Color.GRAY },
            Stop { offset: 0.5 color: Color.BLACK }
        ]
    }
}

var tagTextBox : TextBox = TextBox {
    promptText: "Search Tags"
    action: function() {
        search();
    }
}

var searchButton : Button = Button {
    text: "Search"
    strong: true
    action: function() {
        search();
    }
}

var searchBox : HBox = HBox {
    spacing: 10
    translateX: bind (width - searchBox.boundsInLocal.width - 50)
    translateY: bind (bottomRect.y + (bottomRect.height - searchBox.height)/2.0)
    content: [ tagTextBox, searchButton ]
}

var topRect : Rectangle = Rectangle {
    height: bind bottomRect.height
    width: bind width
    fill: LinearGradient {
        startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
        proportional: true
        stops: [
            Stop { offset: 0.5 color: Color.BLACK },
            Stop { offset: 1.0 color: Color.GRAY }
        ]
    }
    onMousePressed: function(e) {
        stageDragInitialX = e.screenX - stage.x;
        stageDragInitialY = e.screenY - stage.y;
    }
    onMouseDragged: function(e) {
        stage.x = e.screenX - stageDragInitialX;
        stage.y = e.screenY - stageDragInitialY;
    }
}

var minButton = ImageButton {
    name: "min"
    onMouseClicked: function(e) {
        stage.fullScreen = false;
        stage.iconified = true;
    }

}

var closeButton = ImageButton {
    name: "close"
    onMouseClicked: function(e) {
        FX.exit();
    }
}

var controlBox : HBox = HBox {
    translateX: bind (width - controlBox.boundsInLocal.width - 15)
    translateY: bind ((topRect.boundsInLocal.height - 24)/2.0)
    content: [ minButton, closeButton ]
    visible: bind ("{__PROFILE__}" != "browser")
}

var scene : Scene = Scene {
    fill: Color.BLACK
    content: [
        thumbGroup, bottomRect, topRect, controlBox, searchBox
    ]
};

var stage : Stage = Stage {
    title: "Mosaic"
    resizable: false
    style: StageStyle.UNDECORATED
    width: 800
    height: 600
    scene: scene
}

function run() {
    loadImageMetadata();
}