/**
   * Obtém a lista de fontes.
   *
   * @return ArrayList com as fontes da App.
   */
  public static Collection<IGEOSource> getSourcesList() {

    if (IGEOConfigsManager.getAppConfigs().getSourcesHashMap() != null) { // se já existe retorna
      return IGEOConfigsManager.getAppConfigs().getSourcesHashMap().values();
    }

    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequestsSources
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;
    JSONObject jsonObj = IGEOJSONServerReader.getJSONObject(url);
    if (jsonObj != null) {
      // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
      ArrayList<IGEOSource> listResult = IGEOUtils.getSourcesFromJSONObject(jsonObj);

      strDensity = null;

      return listResult;
    }

    return null;
  }
  /**
   * Obtém a lista de itens para uma ou mais categorias de uma fonte, num raio de proximidade
   * pré-definido no menu de settings, filtrando por uma string contendo palavras chave.
   *
   * @param srcID ID da fonte.
   * @param catIDList Lista de ID's das categorias.
   * @param filters Palavras-chave usadas na pesquisa.
   * @param loc Localização a utilizar como centro do raio de pesquisa pré-definido.
   * @return ArrayList de DataItems com os dados pretendidos.
   */
  public static ArrayList<IGEOGenericDataItem> getListForSourceAndCategoriesNearFiltered(
      String srcID, ArrayList<String> catIDList, String filters, Location loc) {
    if (catIDList == null) {
      return null;
    }

    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequests
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;

    url += "&sid=" + srcID + "&cats=";

    int i = 0;
    for (String catID : catIDList) {
      url += catID + ";";
      i++;
    }

    url +=
        "&lat="
            + loc.getLatitude()
            + "&lon="
            + loc.getLongitude()
            + "&r="
            + IGEOConfigsManager.getAppConfigs().getProximityRadius();

    // Permite ir buscar todos os itens.
    // Atenção isto deverá de futuro ser alterado para que a paginação seja feita logo na
    // obteção dos dados. Neste momento só está a ser feita na construção da ListView.
    url += "&nr=0";

    if (filters != null) url += "&txt=" + filters;

    Log.i("DGAItems", "url = " + url);

    jsonObj = IGEOJSONServerReader.getJSONObject(url);

    if (jsonObj != null) {
      // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
      listResultData = IGEOUtils.getDataListFromJSONObject(jsonObj);

      return listResultData;
    }

    return null;
  }
  /**
   * Obtém a lista de itens para uma ou mais categorias de uma fonte, num raio de proximidade
   * pré-definido no menu de definições.
   *
   * @param srcID ID da source.
   * @param catIDList Lista de ID's das categorias.
   * @param loc Localização a utilizar como centro do raio de pesquisa pré-definido.
   * @return ArrayList de DataItems com os dados pretendidos.
   */
  public static ArrayList<IGEOGenericDataItem> getListForSourceAndCategoriesNear(
      String srcID, ArrayList<String> catIDList, Location loc) {

    if (catIDList == null) {
      return null;
    }

    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequests
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;
    url = url + "&sid=" + srcID + "&cats=";

    int i = 0;
    for (String catID : catIDList) {
      url += catID + ";";
      i++;
    }

    url +=
        "&lat="
            + loc.getLatitude()
            + "&lon="
            + loc.getLongitude()
            + "&r="
            + IGEOConfigsManager.getAppConfigs().getProximityRadius();

    // permite ir buscar todos os items
    // atenção isto deverá de futuro ser alterado
    url += "&nr=0";

    // Log.i("DGAItems","url = "+url);

    jsonObj = IGEOJSONServerReader.getJSONObject(url);

    if (jsonObj != null) {
      // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
      listResultSources = IGEOUtils.getDataListFromJSONObject(jsonObj);

      return listResultSources;
    }

    return null;
  }
  /**
   * Obtém a lista de categorias disponíveis para uma fonte no raio de próximidade pré-definido de
   * uma localização.
   *
   * @param loc Centro do raio dentro do qual queremos efetuar a pesquisa.
   * @return Lista de categorias disponíveis.
   */
  public static ArrayList<IGEOCategory> getCategoriesListActualSourceInLocation(Location loc) {
    if (actualSource != null) {

      // vai obter o JSONObject
      String strDensity = IGEOConfigsManager.densityString;

      url =
          IGEOConfigsManager.getAppConfigs().URLRequestsCategories
              + "&imgtype="
              + strDensity
              + "&token="
              + TOKEN;
      url =
          url
              + "&sid="
              + IGEODataManager.getActualSource().sourceID
              + "&lat="
              + loc.getLatitude()
              + "&lon="
              + loc.getLongitude()
              + "&r="
              + IGEOConfigsManager.getAppConfigs().getProximityRadius()
              + "&txt=";
      jsonObj = IGEOJSONServerReader.getJSONObject(url);
      if (jsonObj != null) {
        // Faz o parse do JSONObject e transforma-o num ArrayList de Categories
        listResultCats = IGEOUtils.getCategoriesFromJSONObject(jsonObj);

        if (listResultCats != null) {
          IGEODataManager.actualSource.setCategories(listResultCats);
        } else {
          IGEODataManager.actualSource.setCategories(null);
        }

        return listResultCats;
      } else {
        IGEODataManager.actualSource.setCategories(null);
      }
    }

    return null;
  }
  /**
   * Obtém as configurações por defeito, ou seja, a imagem por defeito da home, a imagem por defeito
   * da lista, entre outras.
   */
  public static void readJSONAppDefaultsFromServer() {
    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequestAppDefaults
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;
    JSONObject jsonObj = IGEOJSONServerReader.getJSONObject(url);
    if (jsonObj != null) {
      try {
        IGEOUtils.readAppDefaultsFromJSONObject(jsonObj);
      } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      strDensity = null;
    }
  }
  /**
   * Obtém um item através apenas do seu ID.
   *
   * @param ID ID do item a obter.
   * @return Item pretendido.
   */
  public static IGEOGenericDataItem getDataItemForID(String ID) {

    if (IGEODataItemsCache.getItem(ID) != null) return IGEODataItemsCache.getItem(ID);
    else {
      // Obter o JSON do servidor

      // vai obter o JSONObject
      String strDensity = IGEOConfigsManager.densityString;

      url =
          IGEOConfigsManager.getAppConfigs().URLRequests
              + "&imgtype="
              + strDensity
              + "&token="
              + TOKEN;

      url += "&sdid=" + ID;

      // Log.i("DGAItems","url = "+url);

      jsonObj = IGEOJSONServerReader.getJSONObject(url);

      if (jsonObj != null) {
        // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
        di_geral = IGEOUtils.getDataItemFromJSONObject(jsonObj);
      }

      if (di_geral != null) IGEODataItemsCache.addItem(di_geral);

      url = null;
      jsonObj = null;

      System.gc();

      return di_geral;
    }
  }
  /**
   * Obtém a lista de categorias disponíveis para uma fonte numa localização anteriormente
   * selecionada através da seleção do distrito, concelho e freguesia.
   *
   * @return Lista de categorias disponíveis.
   */
  public static ArrayList<IGEOCategory> getCategoriesListActualSourceInSearchLocation() {
    if (actualSource != null) {

      // vai obter o JSONObject
      String strDensity = IGEOConfigsManager.densityString;

      url =
          IGEOConfigsManager.getAppConfigs().URLRequestsCategories
              + "&imgtype="
              + strDensity
              + "&token="
              + TOKEN;
      url = url + "&sid=" + IGEODataManager.getActualSource().sourceID + "&ine=";
      if (codPar != null) {
        if (!codPar.equals("")) url += codPar;
        else url += codConc;
      } else {
        url += codConc;
      }

      url += "&txt=";

      jsonObj = IGEOJSONServerReader.getJSONObject(url);
      if (jsonObj != null) {
        // Faz o parse do JSONObject e transforma-o num ArrayList de Categories
        listResultCats = IGEOUtils.getCategoriesFromJSONObject(jsonObj);

        if (listResultCats != null) {
          IGEODataManager.actualSource.setCategories(listResultCats);
        }

        return listResultCats;
      }
    }

    return null;
  }
  /**
   * Obtém a lista de itens para uma ou mais categorias de uma fonte, numa localização definida pela
   * filtragem por distrito, concelho e freguesia e por palavras chave.
   *
   * @param srcID ID da fonte.
   * @param catIDList Lista de ID's das categorias.
   * @param filters Palavras-chave usadas na pesquisa.
   * @return ArrayList de DataItems com os dados pretendidos.
   */
  public static ArrayList<IGEOGenericDataItem>
      getListForSourceAndCategoriesInSearchLocationFiltered(
          String srcID, ArrayList<String> catIDList, String filters) {

    if (catIDList == null) {
      return null;
    }

    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequests
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;

    url += "&sid=" + srcID + "&cats=";

    int i = 0;
    for (String catID : catIDList) {
      url += catID + ";";
      i++;
    }

    // permite ir buscar todos os itens
    // atenção isto deverá de futuro ser alterado
    url += "&nr=0";

    if (codPar != null) {
      if (!codPar.equals("")) url += "&ine=" + codPar;
      else url += "&ine=" + codConc;
    } else {
      url += "&ine=" + codConc;
    }

    if (filters != null) url += "&txt=" + filters;

    // Log.i("DGAItems","url = "+url);

    jsonObj = IGEOJSONServerReader.getJSONObject(url);

    if (jsonObj != null) {

      // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
      listResultData = IGEOUtils.getDataListFromJSONObject(jsonObj);

      jsonObj = null;
      url = null;

      System.gc();

      return listResultData;
    }

    jsonObj = null;
    url = null;

    System.gc();

    return null;
  }
  /**
   * Obtém a lista de itens para uma ou mais categorias de uma fonte, numa localização definida pela
   * filtragem por distrito, concelho e freguesia.
   *
   * @param srcID ID da fonte.
   * @param catIDList Lista de ID's das categorias.
   * @return ArrayList de DataItems com os dados pretendidos.
   */
  public static ArrayList<IGEOGenericDataItem> getListForSourceAndCategoriesInSearchLocation(
      String srcID, ArrayList<String> catIDList) {

    if (catIDList == null) {
      return null;
    }

    // vai obter o JSONObject
    String strDensity = IGEOConfigsManager.densityString;

    url =
        IGEOConfigsManager.getAppConfigs().URLRequests
            + "&imgtype="
            + strDensity
            + "&token="
            + TOKEN;

    url += "&sid=" + srcID + "&cats=";

    int i = 0;
    for (String catID : catIDList) {
      url += catID + ";";
      i++;
    }

    // Permite ir buscar todos os itens.
    // Deverá, no futuro, ser alterado para que a paginação seja feita logo na
    // obtenção dos dados. Neste momento só está a ser feita na construção da ListView.
    url += "&nr=0";

    if (codPar != null) {
      if (!codPar.equals("")) url += "&ine=" + codPar;
      else {
        if (codConc != null) {
          if (!codConc.equals("")) {
            url += "&ine=" + codConc;
          } else {
            url += "&ine=" + codDist;
          }
        } else {
          url += "&ine=" + codDist;
        }
      }
    } else {
      if (codConc != null) {
        if (!codConc.equals("")) {
          url += "&ine=" + codConc;
        } else {
          url += "&ine=" + codDist;
        }
      } else {
        url += "&ine=" + codDist;
      }
    }

    Log.i("DGAItems", "url = " + url);

    jsonObj = IGEOJSONServerReader.getJSONObject(url);

    if (jsonObj != null) {

      // Faz o parse do JSONObject e transforma-o num ArrayList de Sources
      listResultData = IGEOUtils.getDataListFromJSONObject(jsonObj);

      jsonObj = null;
      url = null;

      System.gc();

      return listResultData;
    }

    jsonObj = null;
    url = null;

    System.gc();

    return null;
  }