from util import to_float

# sort functions to apply to features


def _sort_features_by_key(features, key):
    features.sort(key=key)
    return features


def _by_feature_property(property_name):
    def _feature_sort_by_property(feature):
        wkb, properties, fid = feature
        return properties.get(property_name)
    return _feature_sort_by_property


_by_feature_id = _by_feature_property('id')


def _sort_by_area_then_id(features):
    features.sort(key=_by_feature_id)
    features.sort(key=_by_feature_property('area'), reverse=True)
    return features


def _by_scalerank(feature):
    wkb, properties, fid = feature
    value_for_none = 1000
    scalerank = properties.get('scalerank', value_for_none)
    return scalerank


def _by_population(feature):
    wkb, properties, fid = feature
    default_value = -1000
    population_flt = to_float(properties.get('population'))
    if population_flt is not None:
        return int(population_flt)
    else:
        return default_value


def _sort_by_scalerank_then_population(features):
    features.sort(key=_by_population, reverse=True)
    features.sort(key=_by_scalerank)
    return features


def _by_transit_routes(feature):
    wkb, props, fid = feature

    num_lines = 0
    transit_routes = props.get('transit_routes')
    if transit_routes is not None:
        num_lines = len(transit_routes)

    return num_lines


def _sort_by_transit_routes_then_feature_id(features):
    features.sort(key=_by_feature_id)
    features.sort(key=_by_transit_routes, reverse=True)
    return features


def buildings(features, zoom):
    return _sort_by_area_then_id(features)


def earth(features, zoom):
    return _sort_features_by_key(features, _by_feature_id)


def landuse(features, zoom):
    return _sort_by_area_then_id(features)


def places(features, zoom):
    return _sort_by_scalerank_then_population(features)


def pois(features, zoom):
    return _sort_by_transit_routes_then_feature_id(features)


def roads(features, zoom):
    return _sort_features_by_key(features, _by_feature_property('sort_key'))


def water(features, zoom):
    return _sort_by_area_then_id(features)


def transit(features, zoom):
    return _sort_features_by_key(features, _by_feature_id)

from util import to_float

# sort functions to apply to features


def _sort_features_by_key(features, key):
    features.sort(key=key)
    return features


def _by_feature_property(property_name):
    def _feature_sort_by_property(feature):
        wkb, properties, fid = feature
        return properties.get(property_name)
    return _feature_sort_by_property


_by_feature_id = _by_feature_property('id')


def _by_area(feature):
    wkb, properties, fid = feature
    default_value = -1000
    sort_key = properties.get('area', default_value)
    return sort_key


def _sort_by_area_then_id(features):
    features.sort(key=_by_feature_id)
    features.sort(key=_by_area, reverse=True)
    return features


def _by_scalerank(feature):
    wkb, properties, fid = feature
    value_for_none = 1000
    scalerank = properties.get('scalerank', value_for_none)
    return scalerank


def _by_population(feature):
    wkb, properties, fid = feature
    default_value = -1000
    population_flt = to_float(properties.get('population'))
    if population_flt is not None:
        return int(population_flt)
    else:
        return default_value


def _by_transit_routes(feature):
    wkb, props, fid = feature

    num_lines = 0
    transit_routes = props.get('transit_routes')
    if transit_routes is not None:
        num_lines = len(transit_routes)

    return num_lines


def _sort_by_transit_routes_then_feature_id(features):
    features.sort(key=_by_feature_id)
    features.sort(key=_by_transit_routes, reverse=True)
    return features


def buildings(features, zoom):
    return _sort_by_area_then_id(features)


def earth(features, zoom):
    return _sort_features_by_key(features, _by_feature_id)


def landuse(features, zoom):
    return _sort_by_area_then_id(features)


def _place_key_desc(feature):
    sort_key = _by_population(feature), _by_area(feature)
    return sort_key


def places(features, zoom):
    features.sort(key=_place_key_desc, reverse=True)
    features.sort(key=_by_scalerank)
    features.sort(key=_by_feature_property('n_photos'), reverse=True)
    return features


def pois(features, zoom):
    return _sort_by_transit_routes_then_feature_id(features)


def roads(features, zoom):
    return _sort_features_by_key(features, _by_feature_property('sort_key'))


def water(features, zoom):
    return _sort_by_area_then_id(features)


def transit(features, zoom):
    return _sort_features_by_key(features, _by_feature_id)

Update places sort to include n_photos and area