/*----------------------------------------------------------------------------
 * TimeMap Intialization Script
 *
 * @author Nick Rabinowitz (www.nickrabinowitz.com)
 * This is an attempt to create a general initialization script that will
 * work in most cases. If you need a more complex initialization, write your
 * own script instead of using this one.
 *
 * The idea here is to throw all of the standard intialization settings into
 * a large object and then pass it to the timemapInit() function. The full
 * data format is outlined below, but if you leave elements off the script 
 * will use default settings instead.
 *
 * Call timemapInit() inside of an onLoad() function (or a jQuery 
 * $.(document).ready() function, or whatever you prefer).
 *
 * See the examples for usage.
 *
 *---------------------------------------------------------------------------*/
 
/**
 * Intializes a TimeMap.
 *
 * @param {Object} config   Full set of configuration options.
 *                          See examples/timemapinit_usage.js for format.
 */
function hvTimemapInit(config) {
    
    // check required elements
    if (!('mapId' in config) || !config['mapId']) {
        alert("TimeMap init: No map id was specified!");
        return;
    }
    if (!('timelineId' in config) || !config['timelineId']) {
        alert("TimeMap init: No timeline id was specified!");
        return;
    }
    
    var hvTimelineTheme1 = Timeline.ClassicTheme.create();
    // hide dates for first track
    hvTimelineTheme1.ether.interval.marker.hBottomStyler = function(elmt) {
                    elmt.className = "timeline-ether-hide";
                };
    hvTimelineTheme1.ether.interval.marker.hBottomEmphasizedStyler = function(elmt) {
                    elmt.className = "timeline-ether-hide";
                };
    
    var hvTimelineTheme2 = Timeline.ClassicTheme.create();
    hvTimelineTheme2.ether.interval.marker.hBottomEmphasizedStyler = function(elmt) {
                        var date = elmt['innerHTML'] || "";
                        if (date=='901BC') {
                            elmt.innerHTML = '<div class="timeline-period-title">' 
                                + 'Early Iron Age (Western Mediterranean)' + '</div>' + date;
                        }
                };
    
    // set defaults
    config = config || {}; // make sure the config object isn't null
    config['options'] = config['options'] || {};
    config['datasets'] = config['datasets'] || [];
    config['bandInfo'] = config['bandInfo'] || false;
    // ifferent band info
    if (!config['bandInfo']) {
        var intervals = config['bandIntervals'] || 
            [Timeline.DateTime.WEEK, Timeline.DateTime.MONTH];
        config['bandInfo'] = [
    		{
               width:          "60%", 
               intervalUnit:   intervals[0], 
               intervalPixels: 70,
               theme: hvTimelineTheme1
            },
            {
               width:          "25%", 
               intervalUnit:   intervals[0], 
               intervalPixels: 70,
               theme: hvTimelineTheme2
            },
            {
               width:          "15%", 
               intervalUnit:   intervals[1], 
               intervalPixels: 100,
               showEventText:  false,
               trackHeight:    0.2,
               trackGap:       0.1
            }
        ];
    }
    
    // create the TimeMap object
    var tm = new TimeMap(
  		document.getElementById(config['timelineId']), 
		document.getElementById(config['mapId']),
		config['options']
    );
    
    // We're assuming two datasets: one of sites, one of events
    // For the moment, we'll identify by title
    var datasets = [false, false];
    for (var x=0; x < config['datasets'].length; x++) {
        var ds = config['datasets'][x];
        var dsOptions = {};
        dsOptions['title'] = ds['title'] || '';
        if (ds['dateParser']) dsOptions['dateParser'] = ds['dateParser'];
        if (ds['title']=='Events') dsOptions['theme'] = TimeMapDataset.yellowTheme({eventIconPath: hvEventIconPath});
        // just set manually
        var dsIndex = (ds['title']=='Events') ? 1 : 0;
        datasets[dsIndex] = tm.createDataset("ds" + x, dsOptions);
    }
    
    // set up timeline bands
    var bands = [];
    // ensure there's at least an empty eventSource
    for (var x=0; x < config['bandInfo'].length; x++) {
        // set each band to its own event source
        var eventSource = (datasets[x] && datasets[x]['eventSource']) || new Timeline.DefaultEventSource();
        var bandInfo = config['bandInfo'][x];
        // first two bands get diff event sources
        if (x<2) bandInfo['eventSource'] = eventSource;
        else bandInfo['eventSource'] = datasets[0]['eventSource'];
        bands[x] = Timeline.createBandInfo(bandInfo);
    }
    // add period highlight
    for (var i = 0; i < bands.length; i++) {
        bands[i].decorators = [
            new Timeline.SpanHighlightDecorator({
                startDate:  Timeline.DateTime.parseGregorianDateTime("901 BC"),
                endDate:    Timeline.DateTime.parseGregorianDateTime("750 BC"),
                color:      "#ECC04A",
                opacity:    20,
                startLabel: "",
                endLabel:   ""
            })
        ];
    }
    // initialize timeline
    tm.initTimeline(bands);
    
    // set up load manager
    var loadMgr = {};
    loadMgr.count = 0;
    loadMgr.loadTarget = config['datasets'].length;
    loadMgr.ifLoadedFunction = function() {
        var band = tm.timeline.getBand(0);
        var eventSource = band.getEventSource();
        band.setCenterVisibleDate(eventSource.getEarliestDate());
        tm.timeline.layout();
        // zoom out for a slightly broader view
        tm.map.setZoom(tm.map.getZoom()-1);
    };
    loadMgr.ifLoaded = function() {
        this.count++;
        if (this.count == this.loadTarget)
            this.ifLoadedFunction();
    };
    
    // load data!
    for (var x=0; x < config['datasets'].length; x++) {
        (function(x) { // magic trick to deal with closure issues
            var data = config['datasets'][x]['data'];
            var ds = datasets[x];
            // use dummy function as default
            var dummy = function(data) { return data; }
            var preload = config['datasets'][x]['preloadFunction'] || dummy;
            var transform = config['datasets'][x]['transformFunction'] || dummy;
            switch(data['type']) {
                case 'basic':
                    // data already loaded
                    var items = preload(data['value']);
                    ds.loadItems(items, transform);
                    loadMgr.ifLoaded();
                    break;
                case 'json':
                    // data to be loaded from remote json
                    JSONLoader.read(data['url'], function(result) {
                        var items = preload(result);
                        ds.loadItems(items, transform);
                        loadMgr.ifLoaded();
                    });
                    break;
                case 'kml':
                    // data to be loaded from kml file
                    GDownloadUrl(data['url'], function(result) {
                        var items = TimeMapDataset.parseKML(result);
                        items = preload(items);
                        ds.loadItems(items, transform);
                	    loadMgr.ifLoaded();
                    });
                    break;
                case 'metaweb':
                    // data to be loaded from freebase query
                    Metaweb.read(data['query'], function(result) {
                        var items = preload(result);
                        ds.loadItems(result, transform);
                	    loadMgr.ifLoaded();
                    });
                    break;
            }
        })(x);
    }
}
 
