'use strict';

Ox.load.Geo = function(options, callback) {

    Ox.getJSON(Ox.PATH + 'Ox.Geo/json/Ox.Geo.json', function(data) {

        //@ Constants ----------------------------------------------------------

        /*@
        Ox.COUNTRIES <[o]> Array of countries
            A list of independent (or de-facto independent) countries and
            dependencies (see
            <a href="http://en.wikipedia.org/wiki/List_of_sovereign_states">Wikipedia</a>),
            other entities with
            <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a>
            country codes, and former countries according to
            <a href="http://en.wikipedia.org/wiki/ISO_3166-3">ISO 3166-3</a>
            and <a href="http://www.imdb.com/country/">IMDb</a>.
            area <n> Area of the country in square meters
            code <s> ISO 3166-1 alpha-2 country code
            created <o> FIXME: incomplete data
            dependencies <[s]> Array of dependencies of the country
            dependency <[s]> Array of countries the country is a dependency of
            disputed <[s]> Array of countries the country is disputed by
            disputes <[s]> Array of countries the country disputes
            dissolved <o> Present if the country was dissolves
                country <s|[s]> Succeeding country or countries
                date <s> Date of dissolution
                type <s> "joined", "merged", "renamed" or "split"
            east <n> Longitude of eastern boundary in deg
            googleName <s|u> Google Maps country name
            imdbName <s|u> IMDb country name
            languages <[s]> Array of languages that are spoken in this country more than in any other
            lat <n> Latitude of the center in deg
            lng <n> Longitude of the center in deg
            name <s> Name
            north <n> Latitude of northern boundary in deg
            other <b> True if the country is an "other entity" (EU, FX, UK)
            south <n> Latitude of southern boundary in deg
            wikipediaName <s> Wikipedia country name (http://en.wikipedia.org/wiki/$wikipediaName)
            west <n> Longitude of western boundary in deg
            <script>
                Ox.test.array = [
                    // Current independent countries
                    Ox.COUNTRIES.filter(function(c) {
                        return !c.dissolved && !c.dependency && !c.disputed
                    }).length,
                    // Current dependent countries
                    Ox.COUNTRIES.filter(function(c) {
                        return !c.dissolved && c.dependency
                    }).length,
                    // Current disputed countries
                    Ox.COUNTRIES.filter(function(c) {
                        return !c.dissolved && c.disputed
                    }).length,
                    // Dissolved independent countries
                    Ox.COUNTRIES.filter(function(c) {
                        return c.dissolved && !c.dependency && !c.disputed
                    }).length,
                    // Dissolved dependent countries
                    Ox.COUNTRIES.filter(function(c) {
                        return c.dissolved && c.dependency
                    }).length,
                    // Dissolved disputed countries
                    Ox.COUNTRIES.filter(function(c) {
                        return c.dissolved && c.disputed
                    }).length
                ];
            </script>
            > Ox.COUNTRIES.length
            319
            > Ox.sum(Ox.test.array)
            319
            > Ox.test.array
            [202, 77, 6, 22, 11, 1]
        @*/

        Ox.COUNTRIES = data;

        //@ Functions ----------------------------------------------------------

        /*@
        Ox.getCountryByCode <f> Returns a country object for a given country code
            (code) -> <o> Country object
            code <s> ISO 3166 country code
            > Ox.getCountryByCode('US').name
            'United States'
        @*/

        Ox.getCountryByCode = function(code) {
            var country;
            Ox.forEach(Ox.COUNTRIES, function(c) {
                if (c.code == code) {
                    country = c;
                    return false;
                }
            });
            return country;
        };

        /*@
        Ox.getCountryByGeoname <f> Returns a country object for a given geoname
            (name) -> <o> Country object
            name <s> Geoname
            > Ox.getCountryByGeoname('Los Angeles, California, United States').code
            'US'
            > Ox.getCountryByGeoname('The Bottom, Saba, Bonaire, Sint Eustatius and Saba').code
            'BQ'
        @*/

        Ox.getCountryByGeoname = function(geoname) {
            // fixme: UAE correction doesn't belong here, fix in map
            geoname = geoname.replace(' - United Arab Emirates', ', United Arab Emirates')
            return Ox.getCountryByName(
                geoname.split(', ').pop()
                .replace('Sint Eustatius and Saba', 'Bonaire, Sint Eustatius and Saba')
                .replace('Ascension and Tristan da Cunha', 'Saint Helena, Ascension and Tristan da Cunha')
            );
        }

        /*@
        Ox.getCountryByName <f> Returns a country object for a given country name
            (name) -> <o> Country object
            name <s> Country name
            > Ox.getCountryByName('United States').code
            'US'
            > Ox.getCountryByName('USA').code
            'US'
        @*/

        Ox.getCountryByName = function(name) {
            var country;
            Ox.forEach(Ox.COUNTRIES, function(c) {
                if (name == c.name || name == c.googleName || name == c.imdbName) {
                    country = c;
                    return false;
                }
            });
            return country;
        };

        /*@
        Ox.getImageByGeoname <f> Returns an image URL for a given geoname
            (type, size, geoname) -> <s> Image URL
            type <s> Image type ('flag' or 'icon')
            size <n> Image width (32, 256, 2048 (flag), 16, 256, 1024 (icon))
            geoname <s> Geoname
        @*/

        Ox.getFlagByGeoname = function(geoname, size) {
            var country = Ox.getCountryByGeoname(geoname),
                code = country ? country.flag || country.code : 'NTHH';
            return Ox.PATH + 'Ox.Geo/png/flags/' + size + '/' + code + '.png';
        };

        /*@
        Ox.getImageByLanguage <f> Returns an image URL for a given language
            (type, size, geoname) -> <s> Image URL
            type <s> Image type ('flag' or 'icon')
            size <n> Image width (32, 256, 2048 (flag), 16, 256, 1024 (icon))
            language <s> Language
        @*/

        Ox.getFlagByLanguage = function(language, size) {
            language = language
                .replace(' languages', '')
                .replace(' Sign Language', '');
            var country, code;
            Ox.COUNTRIES.forEach(function(c) {
                if (c.languages && c.languages.indexOf(language) > -1) {
                    country = c;
                    return false;
                }
            });
            code = country ? country.flag || country.code : 'NTHH';
            return Ox.PATH + 'Ox.Geo/png/flags/' + size + '/' + code + '.png';
        };

        callback(true);

    });

}