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

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.media.Media;
import podcastfeedviewer.PodcastParser;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Color;
import javafx.scene.paint.Stop;
import javafx.util.Sequences;
import podcastfeedviewer.LocationControll;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.stage.StageStyle;
import javafx.scene.effect.Glow;
import javafx.date.DateTime;
import podcastfeedviewer.media.MediaBox;

/**
 * @author Raghu Nair
 */

//profile check.
public def desktop = "{__PROFILE__}".equals("desktop");
public def mobile = "{__PROFILE__}".equals("mobile");
public def browser = "{__PROFILE__}".equals("browser");

//Width and Hight ration depending on the size change.
def mobileXRatio = 0.375 ;
def mobileYRatio = 0.6667 ;
def mobileXLandScapeRatio = 0.5;
def mobileYLandScapeRatio = 0.5;
def appletRatioX = 0.9375;
def appletRatioY = 0.9375;

//Width ration while loading it changes based on applet,mobile and desktop.
//Desktop 640x480, mobile 320x240 , applet 600x450
public var widthRatio1 = if (mobile) 0.375 else if (browser) 0.9375 else 1;
public var heightRatio1 =if (mobile) 0.6667 else if (browser) 0.9375 else 1;


/* Default width for Desktop Profile*/
public var defaultWidth = bind (640 * widthRatio1);

/* Default height for Desktop Profile*/
public var defaultHeight = bind (480 * heightRatio1);

/* Interval at which the feeds to be polled*/
public var feedInterval = 20m;

/* size of the icons used. */
public def iconSize = bind (50.0 *widthRatio1);

/* gap between controlls */
public def gap = bind (20.0 * widthRatio1);

/* button gap */
public def buttonGap = bind (5 * widthRatio1);

/* Location control height */
public def toolbarHieght = bind (55 * heightRatio1);

/* text box size */
public def textBoxSize = bind (250 * widthRatio1);

/* previous , next media translation */
public def mediaButtonGap = bind (5 * widthRatio1);

/* Title of the appliation used for persisting */
public def applicationTitle = "PodcastViewer";

/* Title of the displayed Feed */
var displayFeedTitle:String = "Podcast Viewer";

/* Currently displaying podcast Feed */
public var currentPodcastFeed:PodcastFeed on replace {
    if ( currentPodcastFeed != null ){
        displayFeedTitle = currentPodcastFeed.title;
        currentPodcastMedia = currentPodcastFeed.medias[0];
    }
}

/*location array for all the feeds which are currently added*/
public var locations:String[];

/* Location TooBar */
public var locationControll = LocationControll{
    width:bind defaultWidth
    height: bind (toolbarHieght - 5 *heightRatio1)
};

/* current location */
public var location:String on replace oldLocation{
    Main.log("Location changed {location} - oldLocation {oldLocation}");
    mediaBox.loading = true;
    currentPodcastFeed = PodcastParser.getPodcastFeed(location);

    if ( currentPodcastFeed == null and location != null and location != ""){
        var parser = PodcastParser{
            location:location
        }        
    }
}


/* Currently playing Podcast Media */
public var currentPodcastMedia:PodcastMedia on replace {
    if ( currentPodcastMedia != null ){
        mediaBox.loading = false;
    }
}

/* Media Box */
public-read var mediaBox:MediaBox = MediaBox {
    visible: true
    mediaPlayerAutoPlay: true
    mediaViewHeight: bind (defaultHeight - locationControll.height - iconSize - gap)
    mediaViewWidth: bind defaultWidth
    translateY: bind locationControll.height + 5 * heightRatio1
    mediaSourceURL:bind currentPodcastMedia.mediaURL
    mediaTitle: bind currentPodcastMedia.title
    //mediaDescription: bind currentPodcastMedia.data
}

/* Navigation button for getting previous media from the current feed */
var previousMedia:ImageView = ImageView{
    fitHeight: bind iconSize
    fitWidth: bind iconSize
    translateY: bind (defaultHeight - iconSize - gap) + 5 * heightRatio1;
    translateX: bind mediaButtonGap
    image: Image{ url:"{__DIR__}resources/arrow_left.png"}
    onMouseEntered: function(e:MouseEvent){
        previousMedia.effect = Glow {}
    }

    onMouseExited: function(e:MouseEvent){
        previousMedia.effect = null;
    }

    onMousePressed:function(e:MouseEvent){
        if ( currentPodcastFeed == null ){
            return;
        }

        var index = Sequences.indexOf(currentPodcastFeed.medias,currentPodcastMedia);

        if ( index == 0){
            index = sizeof currentPodcastFeed.medias - 1;
        }else index --;
        log("Clicked previous -> index = {index}\n size -> {sizeof currentPodcastFeed.medias}");
        if ( currentPodcastMedia .mediaURL != currentPodcastFeed.medias[index].mediaURL)
            currentPodcastMedia = currentPodcastFeed.medias[index];
    }

}

/* Control to goto next media from the current feed */
var nextMedia:ImageView = ImageView{
    translateY: bind (defaultHeight - iconSize - gap) + 5 * heightRatio1;
    translateX: bind ( defaultWidth - (iconSize+5 * heightRatio1));
    fitHeight: bind iconSize
    fitWidth: bind iconSize
    image: Image{ url:"{__DIR__}resources/arrow_right.png"}
    onMouseEntered: function(e:MouseEvent){
        nextMedia.effect = Glow {}
    }

    onMouseExited: function(e:MouseEvent){
        nextMedia.effect = null
    }

    onMousePressed:function(e:MouseEvent){
        if ( currentPodcastFeed == null ){
            return;
        }

        var index = Sequences.indexOf(currentPodcastFeed.medias,currentPodcastMedia);
        log("Clicked next -> index = {index}\n size -> {sizeof currentPodcastFeed.medias}");
        if ( index >= (sizeof currentPodcastFeed.medias - 1)){
            index = 0;
        }else index ++;
        currentPodcastMedia = currentPodcastFeed.medias[index];
    }

}

/* Media description will be displayed here. */
var mediaDescription:Text = Text {
    translateX: bind (iconSize + 2 * buttonGap)
    translateY: bind (defaultHeight - iconSize)
    font : Font {
        size:  (12 * widthRatio1)as Integer
    }
    wrappingWidth:  bind (defaultWidth - (2*iconSize) - 2* buttonGap)* 0.95
    content: bind if( currentPodcastMedia != null)
        "{currentPodcastMedia.title} - {currentPodcastMedia.data}" else "";
}

// Application Title-Bar
var titleBar:Rectangle = Rectangle {
    width: bind defaultWidth
    height: bind 5 * heightRatio1
    fill: Color.TRANSPARENT
    visible: bind ("{__PROFILE__}" != "browser")
    onMouseDragged: function(e) {
        stage.x = stage.x + e.dragX;
        stage.y = stage.y + e.dragY;
    }
}


// Dispose Application
var closeButton:ImageView =  ImageView{

    translateX: bind (defaultWidth - iconSize * 0.25 )
    translateY: 0.0
    image: Image{url: "{__DIR__}resources/close.png"}
    visible : bind ("{__PROFILE__}" != "browser")
    fitHeight: bind iconSize * 0.25
    fitWidth: bind iconSize * 0.25
    opacity:1.0
    onMouseEntered: function(e:MouseEvent){
        closeButton.effect = Glow{}
    }

    onMouseExited: function(e:MouseEvent){
        closeButton.effect =  null;
    }

    onMousePressed: function(e) {
        javafx.lang.FX.exit();
    }
}

/* debugging purpose */
public var VERBOSE =  true;

/* logging purpose */
public function log(e){
    if (VERBOSE)
    println(e);
}

var scene = Scene {
    content: Group {
        content:[mediaBox,
            locationControll,previousMedia,nextMedia,mediaDescription,closeButton]
    }
}

/* Used for mobile landscape notification */
var firstLoad = true;
var height = bind scene.height on replace {
    if (not firstLoad and mobile){
        //Change the ration to mobile Land Scape.
        widthRatio1 = mobileXLandScapeRatio;
        heightRatio1 = mobileYLandScapeRatio;
    }
    firstLoad = false;
}

var stage:Stage =  Stage {
    resizable:false
    title: bind displayFeedTitle
    width: bind defaultWidth
    height:bind defaultHeight
    scene: scene
    style: StageStyle.TRANSPARENT
}


public function run(){
    stage;
    //Load From persistence store.
    PersistenceHandler.load();
}