/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */

/**
 * @requires OpenLayers/Format/JSON.js
 * @requires OpenLayers/Feature/Vector.js
 * @requires OpenLayers/Geometry/Point.js
 * @requires OpenLayers/Geometry/MultiPoint.js
 * @requires OpenLayers/Geometry/LineString.js
 * @requires OpenLayers/Geometry/MultiLineString.js
 * @requires OpenLayers/Geometry/Polygon.js
 * @requires OpenLayers/Geometry/MultiPolygon.js
 * @requires OpenLayers/Console.js
 */

/**
 * Class: OpenLayers.Format.GeoJSON
 * Read and write GeoJSON. Create a new parser with the
 *     <OpenLayers.Format.GeoJSON> constructor.
 *
 * Inherits from:
 *  - <OpenLayers.Format.JSON>
 */
OpenLayers.Format.PANORAMIO = OpenLayers.Class(OpenLayers.Format.JSON, {

    /**
     * APIProperty: ignoreExtraDims
     * {Boolean} Ignore dimensions higher than 2 when reading geometry
     * coordinates.
     */
    ignoreExtraDims: false,

    /**
     * Constructor: OpenLayers.Format.GeoJSON
     * Create a new parser for GeoJSON.
     *
     * Parameters:
     * options - {Object} An optional object whose properties will be set on
     *     this instance.
     */
    initialize: function(options) {
        OpenLayers.Format.JSON.prototype.initialize.apply(this, [options]);
    },

    /**
     * APIMethod: read
     * Deserialize a GeoJSON string.
     *
     * Parameters:
     * json - {String} A GeoJSON string
     * type - {String} Optional string that determines the structure of
     *     the output.  Supported values are "Geometry", "Feature", and
     *     "FeatureCollection".  If absent or null, a default of
     *     "FeatureCollection" is assumed.
     * filter - {Function} A function which will be called for every key and
     *     value at every level of the final result. Each value will be
     *     replaced by the result of the filter function. This can be used to
     *     reform generic objects into instances of classes, or to transform
     *     date strings into Date objects.
     *
     * Returns:
     * {Object} The return depends on the value of the type argument. If type
     *     is "FeatureCollection" (the default), the return will be an array
     *     of <OpenLayers.Feature.Vector>. If type is "Geometry", the input json
     *     must represent a single geometry, and the return will be an
     *     <OpenLayers.Geometry>.  If type is "Feature", the input json must
     *     represent a single feature, and the return will be an
     *     <OpenLayers.Feature.Vector>.
     */
    read: function(json, type, filter) {
        if(this.options && this.options.type)
            type = this.options.type;
        type = (type) ? type : "Panoramio";
        var results = null;
        var obj = null;
        if (typeof json == "string") {
            obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]);
        } else {
            obj = json;
        }



        if(!obj) {
            console.log("Bad JSON: " + json);
            OpenLayers.Console.error("Bad JSON: " + json);
//        } else if(typeof(obj.type) != "string") {
//            OpenLayers.Console.error("Bad GeoJSON - no type: " + json);
        } else {
            obj.type = type;
            this.type = obj["type"];
            this.count = obj["count"];
            this.has_more = obj["has_more"];
            results = [];
            for(var i=0, len=obj.photos.length; i<len; ++i) {
                try {
                    results.push(this.parseFeature(obj.photos[i]));
                } catch(err) {
                    results = null;
                    OpenLayers.Console.error(err);
                }
            }
        }
        return results;
    },

    /**
     * Method: parseFeature
     * Convert a feature object from GeoJSON into an
     *     <OpenLayers.Feature.Vector>.
     *
     * Parameters:
     * obj - {Object} An object created from a GeoJSON object
     *
     * Returns:
     * {<OpenLayers.Feature.Vector>} A feature.
     */
    parseFeature: function(obj) {
        var feature, geometry, attributes;
        attributes = (obj) ? obj : {};

        if(!obj["kategorie"])
            attributes["kategorie"] = "Panoramio";

        if(obj["photo_title"])
            attributes["name"] =  obj["photo_title"];
        else
            attributes["name"] = "::" + obj["photo_id"] + "::";
        attributes["description"] = "<img src='" + obj["photo_file_url"] + "'><br><span style='font-size:8px;'>" + obj["owner_name"] + "::" + obj["upload_date"] + "</span>";

        try {
            geometry = this.parseGeometry(obj);
        } catch(err) {
            // deal with bad geometries
            throw err;
        }
        feature = new OpenLayers.Feature.Vector(geometry, attributes);
        if(obj.id) {
            feature.fid = obj.id;
        }
        return feature;
    },

    /**
     * Method: parseGeometry
     * Convert a geometry object from Panoramio JSON into an <OpenLayers.Geometry>.
     *
     * Parameters:
     * obj - {Object} An object created from a Panoramio photos JSON object
     *
     * Returns:
     * {<OpenLayers.Geometry>} A geometry.
     */
    parseGeometry: function(obj) {
        if (obj == null) {
            return null;
        }
        var geometry;
        geometry = new OpenLayers.Geometry.Point(obj["longitude"], obj["latitude"]);

        // We don't reproject collections because the children are reprojected
        // for us when they are created.
        if (this.internalProjection && this.externalProjection) {
            geometry.transform(this.externalProjection,
                               this.internalProjection);
        }
        return geometry;
    },

    CLASS_NAME: "OpenLayers.Format.PANORAMIO"

});


