var TWIFLU = {
    rpp: 50,
    results: {},
    markers: {},
    articles: []
};

function initialize() {
    TWIFLU.map = new google.maps.Map2(document.getElementById("map"));
    var mapControl = new GMapTypeControl();
    TWIFLU.map.addControl(mapControl);
    TWIFLU.map.addControl(new GLargeMapControl());

    if (window.location.hash) {
        if (window.location.hash.match(/^#address=(.+),range=([\d\.]+)km$/)) {
            var address = RegExp.$1;
            var range = RegExp.$2;
            $('#address').val(address);
            $('#range').val(range);
            loadDataByAddress();
        }
        else if (window.location.hash.match(/^#lat=([\d\.]+),lng=([\d\.]+),range=([\d\.]+)km$/)) {
            var lat = RegExp.$1;
            var lng = RegExp.$2;
            var range = RegExp.$3;
            $('#range').val(range);
            loadDataByLatLng(new google.maps.LatLng(lat, lng));
        } else {
            alert('パラメータが不正です');
        }
    } else {
        $('#address').val('渋谷');
        $('#range').val('3');
        loadDataByAddress();
    }
}

function searchByAddress() {
    TWIFLU.map.clearOverlays();
    $('#results').text('');
    window.location.href = [
        window.location.pathname,
        '#address=' + encodeURIComponent($('#address').val()),
        ',range=' + encodeURIComponent($('#range').val()) + 'km'
    ].join('');
    loadDataByAddress();
    return false;
}

function searchByMap() {
    TWIFLU.map.clearOverlays();
    $('#results').text('');
    var center = TWIFLU.map.getCenter();
    window.location.href = [
        window.location.pathname,
        '#lat=' + encodeURIComponent(center.lat()),
        ',lng=' + encodeURIComponent(center.lng()),
        ',range=' + encodeURIComponent($('#range').val()) + 'km'
    ].join('');
    loadDataByLatLng(center);
    return false;
}

function loadDataByAddress() {
    var address = $('#address').val();
    var geocoder = new google.maps.ClientGeocoder();
    geocoder.getLatLng(address, function(point) {
        var zoom = 13;
        if (TWIFLU.map.getZoom()) {
            zoom = TWIFLU.map.getZoom();
        }
        TWIFLU.map.setCenter(point, zoom);
        requestJson({
            lat: point.lat(),
            lng: point.lng(),
            address: address,
            range: $('#range').val()
        });
    });
}

function loadDataByLatLng(center) {
    var zoom = 13;
    if (TWIFLU.map.getZoom()) {
        zoom = TWIFLU.map.getZoom();
    }
    TWIFLU.map.setCenter(center, zoom);
    var geocoder = new google.maps.ClientGeocoder();
    geocoder.getLocations(center, function(response) {
        $('#address').val(response.Placemark[0].address);
        requestJson({
            lat: center.lat(),
            lng: center.lng(),
            address: response.Placemark[0].address,
            range: $('#range').val()
        });
    });
}

function requestJson(options) {
    var endPoint = 'http://search.twitter.com/search.json?';
    var query = [
        'q=' + encodeURIComponent('インフルエンザ OR インフル OR 学級閉鎖 OR 学校閉鎖 OR タミフル OR リレンザ OR ワクチン'),
        'geocode=' + encodeURIComponent(options.lat) + ',' + encodeURIComponent(options.lng) + ',' + encodeURIComponent(options.range) + 'km',
        'page=1',
        'rpp=' + TWIFLU.rpp,
        'result_type=recent',
        'callback=putMarkers'
    ].join('&');
    endPoint = endPoint + query;
    showNowLoading();
    var script = document.createElement('script');
    script.charset = 'UTF-8';
    script.src = endPoint;
    $('head:first').append(script);
}

function putMarkers(json) {
    hideNowLoading();
    if (json.results.length == 0) {
        $('#results').append($('<li></li>').text('検索結果は 0 件でした。距離を広げて検索してみよう！'));
    }
    for(var i = 0; i < json.results.length; i++) {
        TWIFLU.results[json.results[i].id] = json.results[i];
        putMarker(json.results[i]);
        var d = new Date(json.results[i].created_at);
        var createdAt = d.getFullYear() + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
        $('#results').append(
            $('<div class="tweet clickable"></div>').append(
                $('<div class="image"></div>').append(
                    $('<img width="24" height="24" />').attr('src', json.results[i].profile_image_url)
                )
            ).append(
                $('<div class="comment"></div>').text(json.results[i].text)
            ).append(
                $('<div class="clear date right"></div>').text(createdAt)
            ).attr('id', json.results[i].id).click(function() {
                openMarker(this.id);
                searchResultClass(this.id);
            })
        );
    }
}

function putMarker(tweet) {
    if (tweet.location.match(/^[^\d]*([\d\.]+),([\d\.]+)$/i)) {
        var lat = RegExp.$1;
        var lng = RegExp.$2;
        lat = lat * 1.0 + 0.006 * Math.random();
        lng = lng * 1.0 + 0.006 * Math.random();
        var marker = new google.maps.Marker(new google.maps.LatLng(lat, lng), {
            icon: markerIcon(tweet)
        });
        TWIFLU.map.addOverlay(marker);
        marker.bindInfoWindowHtml(infoWindowHtml(tweet))
        marker.id = tweet.id;
        TWIFLU.markers[tweet.id] = marker;
        google.maps.Event.addListener(marker, 'click', function(latlng) {
            scrollSearchResult(this.id);
            searchResultClass(this.id);
        });
    }
}

function openMarker(id) {
    var tweet = TWIFLU.results[id];
    if (TWIFLU.markers[id]) {
        TWIFLU.markers[id].openInfoWindowHtml(infoWindowHtml(tweet));
    } else {
        var geocoder = new google.maps.ClientGeocoder();
        geocoder.getLatLng(tweet.location, function(point) {
            if (point) {
                var marker = new google.maps.Marker(point, {
                    icon: markerIcon(tweet)
                });
                TWIFLU.map.addOverlay(marker);
                marker.bindInfoWindowHtml(infoWindowHtml(tweet))
                marker.id = tweet.id;
                TWIFLU.markers[id] = marker;
                marker.openInfoWindowHtml(infoWindowHtml(tweet));
                google.maps.Event.addListener(marker, 'click', function(latlng) {
                    scrollSearchResult(this.id);
                    searchResultClass(this.id);
                });
            }
        });
    }
}
function infoWindowHtml(tweet) {
    var html = [
        '<div style="width:200px">',
        '<a href="http://twitter.com/',
        tweet.from_user + '" class="twitter-anywhere-user" target="_blank">',
        tweet.from_user + '</a> ' ,
        tweet.text + ' ',
        '[<a href="http://twitter.com/',
        tweet.from_user + '/statuses/',
        tweet.id + '" target="_blank">source</a>]',
        '</div>'
    ].join('');
    return html;
}
function markerIcon(tweet) {
    var icon = new google.maps.Icon(null, tweet.profile_image_url);
    icon.iconSize = new google.maps.Size(36, 36);
    icon.iconAnchor = new google.maps.Point(18, 18);
    icon.infoWindowAnchor = new google.maps.Point(32, 0);
    return icon;
}

function showNowLoading() {
    $('#now-loading').show();
}
function hideNowLoading() {
    $('#now-loading').hide();
}

function headerSearch() {
    window.location.href = [
        '/map#address=',
        encodeURIComponent($('#address').val()),
        ',range=',
        encodeURIComponent($('#range').val()),
        'km'
    ].join('');
    return false;
}
function userSearch() {
    if ($('#user_name').val() == '') {
        alert('ユーザー名を入力してください。');
        return false;
    }
    window.location.href = [
        '/user/',
        encodeURIComponent($('#user_name').val())
    ].join('');
    return false;
}

/* news */
function newsInitialize() {
    TWIFLU.map = new google.maps.Map2(document.getElementById("map"));
    var mapControl = new GMapTypeControl();
    TWIFLU.map.addControl(mapControl);
    TWIFLU.map.addControl(new GLargeMapControl());
    for (var i = 0; i < TWIFLU.articles.length; i++) {
        if (TWIFLU.articles[i].keywords[0]) {
            var k = TWIFLU.articles[i].keywords[0];
            var center = new google.maps.LatLng(k.lat, k.lng);
            TWIFLU.map.setCenter(center, 7);
            break;
        }
    }
    if (window.location.hash) {
        if (window.location.hash.match(/^#([0-9]+)$/)) {
            TWIFLU.firstOpenMarkerId = RegExp.$1;
        }
    }
    listNews();
}

function listNews() {
    for (var i = 0; i < TWIFLU.articles.length; i++) {
        var markerPut = false;
        for (var j = 0; j < TWIFLU.articles[i].keywords.length; j++) {
            if (TWIFLU.articles[i]['keywords'][j].in_title == 1) {
                appendArticle(i, j, TWIFLU.articles[i].id);
                markerPut = true;
                break;
            }
        }
        if (!markerPut && TWIFLU.articles[i].keywords[0]) {
            appendArticle(i, 0, TWIFLU.articles[i].id);
        }
    }
}
function appendArticle(i, j, articleId) {
    $('#news-list').append(
        $('<div class="entry clickable"></div>')
        .append(
            $('<div class="title"></div>').text(TWIFLU.articles[i].id + '. ' + TWIFLU.articles[i].title)
        ).append(
            $('<div class="clear date right"></div>').text(TWIFLU.articles[i].published_at)
        ).attr('id', 'article-' + i).click(function() {
            openNewsMarker(this.id);
            window.location.hash = articleId;
            newsListClass(this.id);
        })
    );
    var article = TWIFLU.articles[i];
    var point = new google.maps.LatLng(article.keywords[j].lat, article.keywords[j].lng);
    var marker = new google.maps.Marker(point, {
        icon: newsMarkerIcon()
    });
    TWIFLU.map.addOverlay(marker);
    marker.bindInfoWindowHtml(newsInfoWindowHtml(article));
    marker.index = i;
    marker.articleId = articleId;
    google.maps.Event.addListener(marker, 'click', function(latlng) {
        newsListClass('article-' + this.index);
        window.location.hash = this.articleId;
        scrollNewsList(this.index);
    });
    TWIFLU.markers[i] = marker;
    if (TWIFLU.firstOpenMarkerId) {
        if (TWIFLU.firstOpenMarkerId == article.id) {
            scrollNewsList(i);
            newsListClass('article-' + i);
            marker.openInfoWindowHtml(newsInfoWindowHtml(article));
        }
    }
}
function newsInfoWindowHtml(article) {
    var k = [];
    for (var i = 0; i < article.keywords.length; i++) {
        k.push(article.keywords[i].keyword);
    }
    var html = [
        '<div style="width:200px">',
        article.id,
        '. <a href="',
        article.url + '" target="_blank">',
        article.title + '</a>',
        '<p style="margin:4px 0;color:#444;">' + k.join(', ') + '</p>',
        '</div>'
    ].join('');
    return html;
}
function openNewsMarker(id) {
    id.match(/^article-([0-9]+)$/);
    var index = RegExp.$1;
    var article = TWIFLU.articles[index];
    TWIFLU.markers[index].openInfoWindowHtml(newsInfoWindowHtml(article));
}
function newsListClass(id) {
    $('#news-list .entry').each(function() {
        if (this.id == id) {
            $(this).addClass('on');
        } else {
            $(this).removeClass('on');
        }
    });
}
function searchResultClass(id) {
    $('#results .tweet').each(function() {
        if (this.id == id) {
            $(this).addClass('on');
        } else {
            $(this).removeClass('on');
        }
    });
}
function scrollNewsList(index) {
    $('#news-list').scrollTo($('#article-' + index), 300);
}
function scrollSearchResult(id) {
    $('#results').scrollTo($('#' + id), 300);
}
function newsMarkerIcon() {
    var icon = new google.maps.Icon(null, 'http://twiflu.com/img/news-paper.gif');
    icon.shadow = 'http://twiflu.com/img/news-paper-shadow.png';
    icon.shadowSize = new google.maps.Size(47,39);
    icon.iconSize = new google.maps.Size(35, 37);
    icon.iconAnchor = new google.maps.Point(18, 18);
    icon.infoWindowAnchor = new google.maps.Point(32, 0);
    return icon;
}
