// ==UserScript==
// @name          Trackbacker in Flickr for ALPSLAB base
// @version       0.1
// @description   TAF - Trackback to ALPSLAB base in flickr
// @namespace     http://www.luckypines.com/
// @include       http://www*.flickr.com/photos/*
// @include       http://flickr.com/photos/*

// Description
// ===========
// This script will send trackback ping to ALPSLAB Base if the photo is geotagged.
// GeoConv is ported from geoconv.pl by permission of YAMANEKO / Mao san, the original author.
// Please visit http://blog.yamamaya.com/archives/254438.html for more information about geoconv.pl.
// This script is also heavily inspired by GMiF - Display Google Maps in flickr.
// See http://www.flickr.com/groups/flickr_tools/ for more information about GMiF.
// 
// ALPSLAB: http://base.alpslab.jp/
// ALPSLAB Base: http://www.alpslab.jp/
//
// Credits
// =======
// v0.1 Created by Fumiaki Yoshimatsu ( http://www.flickr.com/photos/luckypines/ )
//    - Initial product
//    - YAMANEKO / Mao-san was kindly granted porting geoconv.pl to JavaScript.
//    - Kudos to ALPSLAB team for their innovative products/services.
//    - Script is heavily inspired by GMiF - Display Google Maps in flickr.

GeoConv = new function() {
    var rd = 0.017453292519943295769236907684886;
    var geo_param = {
        'WGS-84' : {
            'a' : 6378137,
            '1/f' : 298.257223563,
            'dx' : 0,
            'dy' : 0,
            'dz' : 0
        },
        'Tokyo' : {
            'a' : 6377397.155,
            '1/f' : 299.152813,
            'dx' : 148,
            'dy' : -507,
            'dz' : -681
        }
    };

    this.convert = function(geo_from, geo_to, longitude_in, latitude_in, altitude) {
//        var longitude = longitude_in[0] + longitude_in[1]/60 + longitude_in[2]/3600;
//        var latitude = latitude_in[0] + latitude_in[1]/60 + latitude_in[2]/3600;

        var longitude = longitude_in;
        var latitude = latitude_in;

        if ((geo_param[geo_from] == null) || (geo_param[geo_to] == null)) {
            // alert(geo_from + " to " + geo_to " not supported");
            return;
        }
        
        var eccf = this.calc_eccentricity(geo_param[geo_from]['1/f']);

        var xyz = this.ellipsoid_to_rectangular(
            longitude,
            latitude,
            altitude,
            geo_param[geo_from]['a'],
            eccf
        );

        var ecct = this.calc_eccentricity(geo_param[geo_to]['1/f']);
        
        var lonlatalt = this.rectangular_to_ellipsoid( 
            xyz.x+geo_param[geo_to]['dx'],
            xyz.y+geo_param[geo_to]['dy'],
            xyz.z+geo_param[geo_to]['dz'], 
            geo_param[geo_to]['a'],
            ecct
        );

//        var longitude_out = this.deg_to_dms(lonlatalt['longitude']);
//        var latitude_out = this.deg_to_dms(lonlatalt['latitude']);

        // hack for base.alpslab.jp...
        var longitude_out = Math.floor(lonlatalt['longitude'] * 3600000);
        var latitude_out = Math.floor(lonlatalt['latitude'] * 3600000);

        var ret = {
            'longitude' : longitude_out,
            'latitude' : latitude_out,
            'altitude' : lonlatalt['altitude']
        };
        return ret;
    }
    
    this.calc_eccentricity = function(i_f) {
        var f = 1/i_f ;
        return 2*f-f*f ;
    }

    this.ellipsoid_to_rectangular = function(b, l, h, a, ec) {
        b *= rd;
        l *= rd;
        if (h = null) h = 0;
        var sb = Math.sin(b);
        var cb = Math.cos(b);
        var cl = Math.cos(l);
        var sl = Math.sin(l);

        var k = a/Math.sqrt(1 - ec*sb*sb) ;
        var x = (k+h) * cb * cl;
        var y = (k+h) * cb * sl ;
        var z = (k*(1-ec)+h) * sb ;

        return {'x':x,'y':y,'z':z};
    }

    this.rectangular_to_ellipsoid = function(x, y, z, a, ec) {
        var sq = Math.sqrt( 1-ec ) ;
        var r1 = Math.sqrt( x*x + y*y ) ;
        var s = Math.atan2( z, r1*sq ) ;
        var st = Math.sin( s ) ;
        var ct = Math.cos( s ) ;
        var b = Math.atan2( z + ec*a / sq*st*st*st, r1 - ec*a*ct*ct*ct ) ;
        var l = Math.atan2( y, x ) ;

        var sb = Math.sin( b ) ;
        var rn = a / Math.sqrt( 1 - ec*sb*sb ) ;
        var h = r1/Math.cos( b ) - rn ;

        return {'longitude':b/rd,'latitude':l/rd,'altitude':h};
    }

    this.deg_to_dms = function(d) {
        var h = Math.floor(d);
        var m = Math.floor( ((d-h)*60) % 60 ) ;
        var s = (d-h-m/60)*3600 ;
        return [h,m,s] ;
    }
};

(function() {

    var imgsrc = "data:image/gif;base64,R0lGODlhLwAYAPcAAMPDw76+vre3t9/f352dnb+/v39/f////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAALwAYAAAIfAAPCBxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgLGtjIsWPGhAYEdhwZ8qNBAwVKDtx4gKVJjQUKtCTI0uVHlShlilwZkuRFlD1RahQZ1OfEnC2FnkzKlOfRmCtB1lTZFCJSmlKTGn14dSjCohxfih1LtqzZs2jTql2LMSAAOw==";
    var imghover = "data:image/gif;base64,R0lGODlhLwAYAPcAAMPDw76+vre3twAAAJ2dnb+/v/8zM////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAALwAYAAAIhgAPCBxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgLGtjIsWPGhAQEdhxp4ONBAgVCEtx4YMAAkwZRFjigUmRJlzBryhxYk6XLny8togxJAGVBlT6B/qS4s+jMmAeSEsQpcafAmjGlDqQK0SpPkDeVcnXolSDWoy2VwlzLtq3bt3Djyp1LF2NAADs=";
    var re = /http:\/\/(www\.)?flickr\.com\/photos\/([^\/]+)\/(\d+)\/?/;
    if( !re.test(document.location) ) return;
    var ownerId = RegExp.$2;
    var photoid = RegExp.$3;
    
    if(unsafeWindow) w = unsafeWindow;
    else w = window;
    global_photos = w.global_photos;

    var button = document.createElement("a");
    var img = document.createElement("img");
    img.src = imgsrc;
    img.addEventListener("mouseover", function(event) { img.src = imghover; }, true);
    img.addEventListener("mouseout", function(event) { img.src = imgsrc; }, true);
    button.addEventListener("click",
        function(event) {
            event.preventDefault();
            var div = document.getElementById("thetags");
            var html = div.innerHTML;
            var re = /tags_rawA.push\('(.+?)'\)\;/ig;
            var ar;
            while ((ar = re.exec(html)) != null) {
                if (ar.length < 1) {
                    continue;
                }
                var relon = /geo:lon=([\d\.]+)$/ig;
                var relat = /geo:lat=([\d\.]+)$/ig;
                var lon,lat;
                if (relon.test(ar[1])) {
                    lon = RegExp.$1;
                } else if (relat.test(ar[1])) {
                    lat = RegExp.$1;
                }
                if (lon && lat) {
                    break;
                }
            }
            if ((lon == null) || (lat == null)) {
                return;
            }
            
            var loc = GeoConv.convert("WGS-84", "Tokyo", lat, lon);
            if (loc == null) {
                return;
            }
            
            var tburl = "http://base.alpslab.jp/bin/tb/" + loc.longitude + "/" + loc.latitude;
            var postdata = "title=" + global_photos[photoid].title
                         + "&url=http://www.flickr.com" + global_photos[photoid].url
                         + "&excerpt=" + encodeURIComponent(global_photos[photoid].description)
                         + "&blog_name=" + ownerId + " photo on Flickr!"

            GM_xmlhttpRequest({
                method: "POST",
                url: tburl,
                data: postdata,
                headers: {
                    "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
                },
                onload: function(response) {
                    //w.alert(response.responseText);
                }
            });
       },
        true);
    button.href = "#";
    button.appendChild(img);
    document.getElementById("button_bar").appendChild(button);
})();

