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.dom.Element;
026    import org.apache.tapestry5.ioc.annotations.Inject;
027    import org.apache.tapestry5.json.JSONObject;
028    import org.apache.tapestry5.services.Request;
029    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
030    import org.chenillekit.google.services.GoogleGeoCoder;
031    
032    
033    /**
034     * Google Map component.
035     *
036     * @version $Id: GPlotter.java 674 2010-07-29 12:47:25Z homburgs $
037     */
038    @SupportsInformalParameters
039    @Import(library = {"../Chenillekit.js", "GPlotter.js"})
040    public class GPlotter implements ClientElement
041    {
042            /**
043             * For blocks, messages, crete actionlink, trigger event.
044             */
045            @Inject
046            private ComponentResources resources;
047    
048            /**
049             * Request object for information on current request.
050             */
051            @Inject
052            private Request request;
053    
054            /**
055             * RenderSupport to get unique client side id.
056             */
057            @Environmental
058            private JavaScriptSupport javascriptSupport;
059    
060            /**
061             * inject our google map service.
062             */
063            @Inject
064            private GoogleGeoCoder geoCoder;
065    
066            /**
067             * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
068             * times, a suffix will be appended to the to id to ensure uniqueness.
069             */
070            @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
071            private String clientId;
072    
073            @Parameter(defaultPrefix = BindingConstants.PROP)
074            private Double lat;
075    
076            @Parameter(defaultPrefix = BindingConstants.PROP)
077            private Double lng;
078    
079            /**
080             * name of a javascript function that acts as error handler.
081             */
082            @Parameter(defaultPrefix = BindingConstants.LITERAL, value = "")
083            private String errorCallbackFunction;
084    
085            @Parameter(defaultPrefix = BindingConstants.LITERAL, value = "")
086            private String dragendCallbackFunction;
087    
088            private String assignedClientId;
089    
090            void setupRender()
091            {
092                    assignedClientId = javascriptSupport.allocateClientId(clientId);
093            }
094    
095            public String getPlotterId()
096            {
097                    return getClientId();
098            }
099    
100            /**
101             * Tapestry render phase method.
102             * Start a tag here, end it in afterRender
103             *
104             * @param writer the markup writer
105             */
106            void beginRender(MarkupWriter writer)
107            {
108                    Element root = writer.getDocument().getRootElement();
109                    Element head = root.find("head");
110    
111                    head.element("script",
112                                             "src", "http://maps.google.com/maps?file=api&v=2&key=" + geoCoder.getKey() + "&hl=" +
113                                                    request.getLocale().getLanguage(),
114                                             "type", "text/javascript",
115                                             "id", "gmap");
116    
117                    writer.element("div", "id", getClientId() + "_map");
118                    resources.renderInformalParameters(writer);
119                    writer.end();
120            }
121    
122            /**
123             * Tapestry render phase method. End a tag here.
124             */
125            void afterRender()
126            {
127                    JSONObject configuration = new JSONObject();
128    
129                    configuration.put("zoomLevel", 13);
130                    configuration.put("smallControl", true);
131                    configuration.put("largeControl", false);
132                    configuration.put("typeControl", true);
133                    configuration.put("label", "location");
134    
135                    configure(configuration);
136    
137                    javascriptSupport.addScript("var %s = new Ck.GPlotter('%s_map', '%s', '%s', '%s', %s);",
138                                                                            getClientId(), getClientId(),
139                                                                            geoCoder.getKey(),
140                                                                            errorCallbackFunction,
141                                                                            dragendCallbackFunction,
142                                                                            configuration.toString());
143    
144                    javascriptSupport.addScript("%s.setCenter(%s, %s);", getClientId(), lat, lng);
145    
146            }
147    
148            /**
149             * for external configuration do override.
150             *
151             * @param jsonObject config object
152             */
153            protected void configure(JSONObject jsonObject)
154            {
155            }
156    
157            /**
158             * Returns a unique id for the element. This value will be unique for any given rendering of a
159             * page. This value is intended for use as the id attribute of the client-side element, and will
160             * be used with any DHTML/Ajax related JavaScript.
161             */
162            public String getClientId()
163            {
164                    return assignedClientId;
165            }
166    }