001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008-2010 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.tapestry.core.components;
016    
017    import org.apache.tapestry5.BindingConstants;
018    import org.apache.tapestry5.ClientElement;
019    import org.apache.tapestry5.ComponentResources;
020    import org.apache.tapestry5.MarkupWriter;
021    import org.apache.tapestry5.annotations.Environmental;
022    import org.apache.tapestry5.annotations.Import;
023    import org.apache.tapestry5.annotations.Parameter;
024    import org.apache.tapestry5.annotations.SupportsInformalParameters;
025    import org.apache.tapestry5.ioc.annotations.Inject;
026    import org.apache.tapestry5.json.JSONObject;
027    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
028    import org.chenillekit.tapestry.core.utils.ProtoTubeIdHolder;
029    
030    import java.util.List;
031    
032    /**
033     * ProtoTube can be used to embed YouTube videos and the respective thumbnails in pages of any web site.
034     * <p/>
035     * This component generates HTML to embed a player to show the video in other Web site pages. The component
036     * may also generate HTML to display thumbnail preview of the videos and display video in a overlay viewer.
037     * ProtoTube is unobtrusive: when javascript is turned off, the page still delivers its core functionality
038     * and is just displayed the link to the Video page on the YouTube site.
039     * <p/>
040     * Would seem to be compatible with IE6, IE7, IE8, Firefox 3.09, Safari 3.2.2, Opera 9.61.
041     * <p/>
042     * <strong>Configuration Options</strong>
043     * <ul>
044     * <li>overlay: default true, if false embed the video player directly</li>
045     * </ul>
046     * <p/>
047     * <strong>Overlay and image preview options:</strong>
048     * <ul>
049     * <li>duration: overlay appare/fade effect duration (default 0.5)</li>
050     * <li>opacity: lightbox overlay opacity (default 0.8)</li>
051     * <li>ImagePreview: show the video thumbs (default true)</li>
052     * <li>imageID: choose between different image previews: value: 0 to 3 (0 = 320x240 jpg , {1,2,3} = 130x97 jpg, default 1)</li>
053     * </ul>
054     * <p/>
055     * <strong>Player options</strong>
056     * <ul>
057     * <li>playerWidth: default 425px</li>
058     * <li>playerHeight: default 350px</li>
059     * <li>fs: 1, allow fullscreen button (default 1, 0 disallow fullscreen)</li>
060     * <li>autoplay: allowed value: 1,0 (default 0)</li>
061     * <li>loop: allowed value: 1,0 (default 0)</li>
062     * <li>hd: Setting to 1 enables High Definition playback by default , if is available; values: 0 or 1 (default 0)</li>
063     * <li>showinfo: Setting to 0 causes the player to not display information like the video title and rating before the video starts playing; values: 0 or 1 (default 1)</li>
064     * <li>rel: show related video at end; values: 0 or 1 (default 1)</li>
065     * </ul>
066     *
067     * @version $Id: ProtoTube.java 674 2010-07-29 12:47:25Z homburgs $
068     */
069    @SupportsInformalParameters
070    @Import(library = {"prototube/prototube.js", "prototube/swfobject.js",
071                    "${tapestry.scriptaculous}/effects.js"},
072                    stylesheet = {"prototube/prototube.css"})
073    public class ProtoTube implements ClientElement
074    {
075            /**
076             * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
077             * times, a suffix will be appended to the to id to ensure uniqueness.
078             */
079            @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
080            private String clientId;
081    
082            /**
083             * list of ProtoTubeIdHolders that contains display information for the YouTube videos.
084             */
085            @Parameter(required = true, defaultPrefix = BindingConstants.PROP)
086            private List<ProtoTubeIdHolder> youtubeIds;
087    
088            @Environmental
089            private JavaScriptSupport javascriptSupport;
090    
091            @Inject
092            private ComponentResources resources;
093    
094            private String assignedClientId;
095    
096            /**
097             * Tapestry render phase method.
098             * Initialize temporary instance variables here.
099             */
100            void setupRender()
101            {
102                    assignedClientId = javascriptSupport.allocateClientId(clientId);
103            }
104    
105    
106            /**
107             * Tapestry render phase method.
108             * Start a tag here, end it in afterRender
109             *
110             * @param writer the markup writer
111             */
112            void beginRender(MarkupWriter writer)
113            {
114                    writer.element("div", "id", getClientId());
115                    resources.renderInformalParameters(writer);
116    
117                    for (ProtoTubeIdHolder youtubeId : youtubeIds)
118                    {
119                            writer.element("a", "href", youtubeId.getId(), "title", youtubeId.getTitle());
120                            writer.end();
121                    }
122    
123                    writer.end();
124            }
125    
126    
127            void afterRender(MarkupWriter writer)
128            {
129                    JSONObject config = new JSONObject();
130    
131                    config.put("hd", 1);
132                    config.put("showinfo", 1);
133    
134                    //
135                    // Let subclasses do more.
136                    //
137                    configure(config);
138    
139                    javascriptSupport.addScript("$$('div#%s a').each( function(el) {new ProtoTube(el, %s);});", getClientId(), config);
140            }
141    
142            /**
143             * Invoked to allow subclasses to further configure the parameters passed to this component's javascript
144             * options. Subclasses may override this method to configure additional features of the ProtoTube.
145             * <p/>
146             * This implementation does nothing.
147             * <p/>
148             * <strong>Configuration Options</strong>
149             * <ul>
150             * <li>overlay: default true, if false embed the video player directly</li>
151             * </ul>
152             * <p/>
153             * <strong>Overlay and image preview options:</strong>
154             * <ul>
155             * <li>duration: overlay appare/fade effect duration (default 0.5)</li>
156             * <li>opacity: lightbox overlay opacity (default 0.8)</li>
157             * <li>ImagePreview: show the video thumbs (default true)</li>
158             * <li>imageID: choose between different image previews: value: 0 to 3 (0 = 320x240 jpg , {1,2,3} = 130x97 jpg, default 1)</li>
159             * </ul>
160             * <p/>
161             * <strong>Player options</strong>
162             * <ul>
163             * <li>playerWidth: default 425px</li>
164             * <li>playerHeight: default 350px</li>
165             * <li>fs: 1, allow fullscreen button (default 1, 0 disallow fullscreen)</li>
166             * <li>autoplay: allowed value: 1,0 (default 0)</li>
167             * <li>loop: allowed value: 1,0 (default 0)</li>
168             * <li>hd: Setting to 1 enables High Definition playback by default , if is available; values: 0 or 1 (default 0)</li>
169             * <li>showinfo: Setting to 0 causes the player to not display information like the video title and rating before the video starts playing; values: 0 or 1 (default 1)</li>
170             * <li>rel: show related video at end; values: 0 or 1 (default 1)</li>
171             * </ul>
172             *
173             * @param config parameters object
174             */
175            protected void configure(JSONObject config)
176            {
177            }
178    
179            /**
180             * Returns a unique id for the element. This value will be unique for any given rendering of a
181             * page. This value is intended for use as the id attribute of the client-side element, and will
182             * be used with any DHTML/Ajax related JavaScript.
183             */
184            public String getClientId()
185            {
186                    return assignedClientId;
187            }
188    }