package com.ejie.aa20b.dao;

import java.sql.Blob;

import com.ejie.x38.dto.Jerarquia;
import com.ejie.x38.dto.Pagination;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.aa20b.model.Edificios;
import com.ejie.aa20b.model.Planos;
import com.ejie.aa20b.model.Plantas;
import com.ejie.aa20b.model.Zonas;

/**
 * PlanosDaoImpl generated by UDA, 12-ene-2015 16:11:59.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class PlanosDaoImpl implements PlanosDao {
	private JdbcTemplate jdbcTemplate;
	private RowMapper<Planos> rwMap = new RowMapper<Planos>() {
		public Planos mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Planos(resultSet.getLong("IDPLANO"),
					resultSet.getLong("IDPADRE"),
					resultSet.getString("IDEDIFICIO"),
					resultSet.getInt("IDZONA"), resultSet.getInt("IDPLANTA"),
					resultSet.getLong("EJEXDESDE"),
					resultSet.getLong("EJEYDESDE"),
					resultSet.getString("EJEXHASTA"),
					resultSet.getLong("EJEYHASTA"),
					resultSet.getString("BAJA"), resultSet.getDate("FEINI"),
					resultSet.getBlob("DIBUJO"));
		}
	};
	private RowMapper<Planos> rwMapLista = new RowMapper<Planos>() {
		public Planos mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			Planos planos = new Planos();

			planos.setIdedificio(resultSet.getString("IDEDIFICIO"));
			planos.setIdpadre(resultSet.getLong("IDPADRE"));
			planos.setIdplano(resultSet.getLong("IDPLANO"));
			planos.setIdzona(resultSet.getInt("IDZONA"));
			planos.setIdplanta(resultSet.getInt("IDPLANTA"));
			planos.setEjexdesde(resultSet.getLong("EJEXDESDE"));
			planos.setEjeydesde(resultSet.getLong("EJEYDESDE"));
			planos.setBaja(resultSet.getString("BAJA"));

			return planos;
		}
	};
	private RowMapper<Planos> rwMapPlanos = new RowMapper<Planos>() {
		public Planos mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			Planos planos = new Planos();

			planos.setIdedificio(resultSet.getString("IDEDIFICIO"));
			planos.setIdpadre(resultSet.getLong("IDPADRE"));
			planos.setIdplano(resultSet.getLong("IDPLANO"));
			planos.setIdzona(resultSet.getInt("IDZONA"));
			planos.setIdplanta(resultSet.getInt("IDPLANTA"));
			planos.setEjexdesde(resultSet.getLong("EJEXDESDE"));
			planos.setEjeydesde(resultSet.getLong("EJEYDESDE"));
			planos.setBaja(resultSet.getString("BAJA"));

			Edificios edificio = new Edificios();
			edificio.setIdedificio(resultSet.getString("IDEDIFICIO"));
			edificio.setCedificio(resultSet.getString("CEDIFICIO"));
			edificio.setEedificio(resultSet.getString("EEDIFICIO"));
			planos.setEdificio(edificio);

			Zonas zona = new Zonas();
			zona.setIdzona(resultSet.getInt("IDZONA"));
			zona.setCzona(resultSet.getString("CZONA"));
			zona.setEzona(resultSet.getString("EZONA"));
			planos.setZona(zona);

			Plantas planta = new Plantas();
			planta.setIdplanta(resultSet.getInt("IDPLANTA"));
			planta.setCplanta(resultSet.getString("CPLANTA"));
			planta.setEplanta(resultSet.getString("EPLANTA"));
			planos.setPlanta(planta);

			return planos;
		}
	};
	private RowMapper<Jerarquia<Planos>> rwMapPlanosJerarquia = new RowMapper<Jerarquia<Planos>>() {
		public Jerarquia<Planos> mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			Planos planos = new Planos();

			planos.setIdedificio(resultSet.getString("IDEDIFICIO"));
			planos.setIdpadre(resultSet.getLong("IDPADRE"));
			planos.setIdplano(resultSet.getLong("IDPLANO"));
			planos.setIdzona(resultSet.getInt("IDZONA"));
			planos.setIdplanta(resultSet.getInt("IDPLANTA"));
			planos.setEjexdesde(resultSet.getLong("EJEXDESDE"));
			planos.setEjeydesde(resultSet.getLong("EJEYDESDE"));
			planos.setBaja(resultSet.getString("BAJA"));

			planos.setDescPlano(resultSet.getString("DESCPLANO"));
			Edificios edificio = new Edificios();
			edificio.setIdedificio(resultSet.getString("IDEDIFICIO"));
			edificio.setCedificio(resultSet.getString("CEDIFICIO"));
			edificio.setEedificio(resultSet.getString("EEDIFICIO"));
			planos.setEdificio(edificio);

			Zonas zona = new Zonas();
			zona.setIdzona(resultSet.getInt("IDZONA"));
			zona.setCzona(resultSet.getString("CZONA"));
			zona.setEzona(resultSet.getString("EZONA"));
			planos.setZona(zona);

			Plantas planta = new Plantas();
			planta.setIdplanta(resultSet.getInt("IDPLANTA"));
			planta.setCplanta(resultSet.getString("CPLANTA"));
			planta.setEplanta(resultSet.getString("EPLANTA"));
			planos.setPlanta(planta);

			Jerarquia<Planos> jerarquia = new Jerarquia<Planos>();
			jerarquia.setModel(planos);
			jerarquia.setLevel(resultSet.getBigDecimal("LEVEL").intValue());
			jerarquia.setHasChildren(Boolean.parseBoolean(resultSet
					.getString("HASCHILDREN")));
			jerarquia.setParentNodes(resultSet.getString("PARENTNODES"));
			jerarquia.setTreeNodes(resultSet.getString("TREENODES"));
			jerarquia.setFilter(Boolean.parseBoolean(resultSet
					.getString("FILTER")));

			return jerarquia;

		}
	};
	private RowMapper<Planos> rwMapDibujo = new RowMapper<Planos>() {
		public Planos mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Planos(null, null, null, null, null, null, null, null,
					null, null, null, resultSet.getBlob("DIBUJO"));
		}
	};

	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * Inserts a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	public Planos add(Planos planos) {
		String query = "INSERT INTO PLANOS (IDPLANO, IDPADRE, IDEDIFICIO, IDZONA, IDPLANTA, EJEXDESDE, EJEYDESDE, EJEXHASTA, EJEYHASTA, BAJA, FEINI, DIBUJO) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
		this.jdbcTemplate.update(query, planos.getIdplano(),
				planos.getIdpadre(), planos.getIdedificio(),
				planos.getIdzona(), planos.getIdplanta(),
				planos.getEjexdesde(), planos.getEjeydesde(),
				planos.getEjexhasta(), planos.getEjeyhasta(),
				planos.getBaja() == null ? "0" : planos.getBaja(),
				planos.getFeini(), planos.getDibujo());
		return planos;
	}

	/**
	 * Inserts a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	public Planos nuevoPlano(Planos planos) {
		// Obtener el id correlativo
		Long idCorrelativo = this.jdbcTemplate
				.queryForLong("SELECT PLANOS_SEQ.NEXTVAL FROM DUAL");

		String query = "INSERT INTO PLANOS (IDPLANO, IDPADRE, IDEDIFICIO, IDZONA, IDPLANTA, BAJA, FEINI, DIBUJO) VALUES (?,?,?,?,?,?,?,?)";
		this.jdbcTemplate.update(query, idCorrelativo, 0,
				planos.getIdedificio(), planos.getIdzona(),
				planos.getIdplanta(), "0", planos.getFeini(),
				planos.getPlanoDibujo());
		planos.setIdplano(idCorrelativo);
		return planos;
	}

	/**
	 * Updates a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	public Planos update(Planos planos) {
		String query = "UPDATE PLANOS SET IDPADRE=?, IDEDIFICIO=?, IDZONA=?, IDPLANTA=?, EJEXDESDE=?, EJEYDESDE=?, EJEXHASTA=?, EJEYHASTA=?, BAJA=?, FEINI=?, DIBUJO=? WHERE IDPLANO=?";
		this.jdbcTemplate.update(query, planos.getIdpadre(),
				planos.getIdedificio(), planos.getIdzona(),
				planos.getIdplanta(), planos.getEjexdesde(),
				planos.getEjeydesde(), planos.getEjexhasta(),
				planos.getEjeyhasta(),
				planos.getBaja() == null ? "0" : planos.getBaja(),
				planos.getFeini(), planos.getDibujo(), planos.getIdplano());
		return planos;
	}

	/**
	 * Updates a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	public Planos asociarPadreHijo(Planos planos) {
		String query = "UPDATE PLANOS SET IDPADRE=?, EJEXDESDE=?, EJEYDESDE=? WHERE IDEDIFICIO=? AND IDZONA=? AND IDPLANTA=?";
		this.jdbcTemplate.update(query, planos.getIdpadre(),
				planos.getEjexdesde(), planos.getEjeydesde(),
				planos.getIdedificio(), planos.getIdzona(),
				planos.getIdplanta());
		return planos;
	}

	/**
	 * modifica el dibujo de un plano.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	public Planos modificaDibujoPlano(Planos planos) {
		String query = "UPDATE PLANOS SET DIBUJO=? WHERE IDPLANO=?";
		this.jdbcTemplate.update(query, planos.getPlanoDibujo(),
				planos.getIdplano());
		return planos;
	}

	/**
	 * Finds a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	@Transactional(readOnly = true)
	public Planos find(Planos planos) {
		String query = "SELECT t1.IDPLANO IDPLANO, t1.IDPADRE IDPADRE, t1.IDEDIFICIO IDEDIFICIO, t1.IDZONA IDZONA, t1.IDPLANTA IDPLANTA, t1.EJEXDESDE EJEXDESDE, t1.EJEYDESDE EJEYDESDE, t1.EJEXHASTA EJEXHASTA, t1.EJEYHASTA EJEYHASTA, t1.BAJA BAJA, t1.FEINI FEINI, t1.DIBUJO DIBUJO FROM PLANOS t1  WHERE t1.IDPLANO = ?  ";

		List<Planos> planosList = this.jdbcTemplate.query(query, this.rwMap,
				planos.getIdplano());
		return (Planos) DataAccessUtils.uniqueResult(planosList);
	}

	/**
	 * Finds a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return Planos
	 */
	@Transactional(readOnly = true)
	public Planos obtenerPlano(Planos planos) {
		String query = "SELECT  t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.IDEDIFICIO IDEDIFICIO, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO,t1.IDZONA IDZONA, t3.CZONA CZONA, t3.EZONA EZONA ,t1.IDPLANTA IDPLANTA, t4.CPLANTA CPLANTA, t4.EPLANTA EPLANTA, t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.EJEXHASTA EJEXHASTA,t1.EJEYHASTA EJEYHASTA,t1.BAJA BAJA,t1.FEINI FEINI,t1.DIBUJO DIBUJO "
				+ " FROM PLANOS t1, EDIFICIOS t2, ZONAS t3, PLANTAS t4 "
				+ " WHERE t1.IDEDIFICIO=t2.IDEDIFICIO AND t1.IDZONA=t3.IDZONA AND t1.IDPLANTA=t4.IDPLANTA "
				+ " AND t1.IDPLANO = ? ";

		List<Planos> planosList = this.jdbcTemplate.query(query,
				this.rwMapPlanos, planos.getIdplano());
		return (Planos) DataAccessUtils.uniqueResult(planosList);
	}

	/**
	 * Removes a single row in the Planos table.
	 * 
	 * @param planos
	 *            Pagination
	 * @return
	 */
	public void remove(Planos planos) {
		String query = "DELETE FROM PLANOS WHERE IDPLANO=?";
		this.jdbcTemplate.update(query, planos.getIdplano());
	}

	/**
	 * Finds a List of rows in the Planos table.
	 * 
	 * @param planos
	 *            Planos
	 * @param pagination
	 *            Pagination
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Planos> findAll(Planos planos, Pagination pagination) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.IDEDIFICIO IDEDIFICIO,t1.IDZONA IDZONA,t1.IDPLANTA IDPLANTA,t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.EJEXHASTA EJEXHASTA,t1.EJEYHASTA EJEYHASTA,t1.BAJA BAJA,t1.FEINI FEINI,t1.DIBUJO DIBUJO ");
		query.append("FROM PLANOS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(planos);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (pagination != null) {
			query = pagination.getPaginationQuery(query);
		}

		return (List<Planos>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, params.toArray());
	}

	/**
	 * Obtener lista de planos para un edificio, zona y planta dado.
	 * 
	 * @param codEdif
	 *            String
	 * @param codPlanta
	 *            Integer
	 * @param codZona
	 *            Integer
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Planos> obtenerListaPlanos(String codEdif, Integer codPlanta,
			Integer codZona) {

		// Primero obtenemos el plano asociado a ese edificio, zona y planta y
		// todos los hijos asociados al plano encontrado
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.IDEDIFICIO IDEDIFICIO,t1.IDZONA IDZONA,t1.IDPLANTA IDPLANTA,t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.BAJA BAJA  ");
		query.append(" FROM PLANOS t1 WHERE (BAJA=0 AND IDEDIFICIO=? AND IDPLANTA=? AND IDZONA=?) ");
		query.append(" or  ( BAJA=0 AND IDPADRE in (SELECT  IDPLANO  FROM PLANOS WHERE (BAJA=0 AND IDEDIFICIO=? AND IDPLANTA=? AND IDZONA=?)))");

		List<Planos> listaPlanos = this.jdbcTemplate.query(query.toString(),
				this.rwMapLista, codEdif, codPlanta, codZona, codEdif,
				codPlanta, codZona);

		return listaPlanos;
	}

	public byte[] buscaDibujo(Planos plano, String idioma) {

		StringBuilder query = new StringBuilder("SELECT t1.DIBUJO DIBUJO ");
		query.append("FROM PLANOS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(plano);
		StringBuilder where = new StringBuilder(" WHERE 1=1");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		List<Planos> planosList = this.jdbcTemplate.query(query.toString(),
				this.rwMapDibujo, params.toArray());
		Planos planoEncontrado = (Planos) DataAccessUtils
				.uniqueResult(planosList);

		byte[] dibujo = null;
		Blob blob = planoEncontrado.getDibujo();
		if (blob != null)
			try {
				dibujo = blob.getBytes(1, (int) blob.length());
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		return dibujo;
	}

	/**
	 * Counts rows in the Planos table.
	 * 
	 * @param planos
	 *            Planos
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllCount(Planos planos) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM PLANOS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(planos);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	/**
	 * Finds rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Planos> findAllLike(Planos planos, Pagination pagination,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.IDEDIFICIO IDEDIFICIO,t1.IDZONA IDZONA,t1.IDPLANTA IDPLANTA,t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.EJEXHASTA EJEXHASTA,t1.EJEYHASTA EJEYHASTA,t1.BAJA BAJA,t1.FEINI FEINI,t1.DIBUJO DIBUJO ");
		query.append("FROM PLANOS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(planos, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (pagination != null) {
			query = pagination.getPaginationQuery(query);
		}

		return (List<Planos>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, params.toArray());
	}

	/**
	 * Finds rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Planos> obtenerPlanos(Planos planos, Pagination pagination,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.IDEDIFICIO IDEDIFICIO, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO,t1.IDZONA IDZONA, t3.CZONA CZONA, t3.EZONA EZONA ,t1.IDPLANTA IDPLANTA, t4.CPLANTA CPLANTA, t4.EPLANTA EPLANTA, t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.EJEXHASTA EJEXHASTA,t1.EJEYHASTA EJEYHASTA,t1.BAJA BAJA,t1.FEINI FEINI,t1.DIBUJO DIBUJO ");
		query.append("FROM PLANOS t1, EDIFICIOS t2, ZONAS t3, PLANTAS t4 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereObtenerPlanos(planos,
				startsWith);
		StringBuilder where = new StringBuilder(
				" WHERE t1.IDEDIFICIO=t2.IDEDIFICIO AND t1.IDZONA=t3.IDZONA AND t1.IDPLANTA=t4.IDPLANTA ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (pagination != null) {
			query = pagination.getPaginationQuery(query);
		}

		return (List<Planos>) this.jdbcTemplate.query(query.toString(),
				this.rwMapPlanos, params.toArray());
	}

	/**
	 * Finds rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Jerarquia<Planos>> obtenerPlanosJerarquia(Planos planos,
			Pagination pagination, Boolean startsWith) {

		// SELECT
		StringBuilder sbSQL = new StringBuilder(
				"SELECT t1.IDPLANO IDPLANO,t1.IDPADRE IDPADRE,t1.DESCPLANO DESCPLANO,t1.IDEDIFICIO IDEDIFICIO, t1.CEDIFICIO CEDIFICIO, t1.EEDIFICIO EEDIFICIO,t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA ,t1.IDPLANTA IDPLANTA, t1.CPLANTA CPLANTA, t1.EPLANTA EPLANTA, t1.EJEXDESDE EJEXDESDE,t1.EJEYDESDE EJEYDESDE,t1.EJEXHASTA EJEXHASTA,t1.EJEYHASTA EJEYHASTA,t1.BAJA BAJA,t1.FEINI FEINI,t1.DIBUJO DIBUJO ");

		// TABLAS
		List<String> from = new ArrayList<String>();
		from.add(" PLANOSJERARQUIA ");

		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add("t1");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereObtenerPlanosJerarquia(planos,
				startsWith);

		// JERARQUIA
		sbSQL = pagination.getQueryJerarquia(sbSQL, mapaWhere, "IDPLANO",
				"IDPADRE", "DESCPLANO", from, from_alias);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (pagination != null) {
			sbSQL = pagination.getPaginationQueryJerarquia(sbSQL);
		}

		return this.jdbcTemplate.query(sbSQL.toString(),
				this.rwMapPlanosJerarquia, params.toArray());

	}

	/**
	 * Counts rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long obtenerPlanosJerarquiaCount(Planos planos, Boolean startsWith,
			Pagination pagination) {

		// SELECT
		StringBuilder sbSQL = new StringBuilder("SELECT COUNT(1) ");

		// TABLAS
		List<String> from = new ArrayList<String>();
		from.add("PLANOSJERARQUIA");

		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add("t1");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereObtenerPlanosJerarquia(planos,
				startsWith);

		// JERARQUIA
		sbSQL = pagination.getQueryJerarquiaCount(sbSQL, mapaWhere, "IDPLANO",
				"IDPADRE", "DESCPLANO", from, from_alias);
		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(sbSQL.toString(),
				params.toArray());

	}

	/**
	 * Counts rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllLikeCount(Planos planos, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM PLANOS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(planos, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	/**
	 * Counts rows in the Planos table using like.
	 * 
	 * @param planos
	 *            Planos
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long obtenerPlanosCount(Planos planos, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM PLANOS t1, EDIFICIOS t2, ZONAS t3, PLANTAS t4 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereObtenerPlanos(planos,
				startsWith);
		StringBuilder where = new StringBuilder(
				" WHERE t1.IDEDIFICIO=t2.IDEDIFICIO AND t1.IDZONA=t3.IDZONA AND t1.IDPLANTA=t4.IDPLANTA ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	// Retorno: page line pk
	public TreeMap<String, TreeMap<String, String>> obtenerPlanosSelect(
			Planos planoJerarquia, Pagination pagination) {

		// SELECT
		StringBuilder sbSQL = new StringBuilder("");

		// TABLAS
		List<String> from = new ArrayList<String>();

		from.add("PLANOSJERARQUIA");

		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add("t1");

		// CONDICIONES (negocio)
		// StringBuilder businessFilters = new StringBuilder();
		// List<Object> businessParams = new ArrayList<Object>();
		// List<String> businessNames = new ArrayList<String>();
		// businessFilters
		// .append("AND t1.EJIE = ? AND t1.EJIE = ? AND t1.EJIE = ?");
		// businessParams.add("1");
		// businessParams.add("1");
		// businessParams.add("1");
		// businessNames.add("EJIE");

		// FILTRO
		Map<String, ?> mapaWhere = this.getWhereObtenerPlanosJerarquia(
				planoJerarquia, false);

		// SELECTED
		sbSQL = pagination.getQuerySelectedGrid(sbSQL, mapaWhere,
				planoJerarquia, "IDPLANO", "IDPADRE", from, from_alias);
		// sbSQL = pagination.getQuerySelectedGrid(sbSQL, mapaWhere,
		// usuarioJerarquia, "ID", "ID_PADRE", from, from_alias, "t1",
		// businessFilters, businessParams, businessNames);

		// System.out.println(sbSQL);

		List<?> params = (List<?>) mapaWhere.get("params");

		// System.out.println(params);

		return this.jdbcTemplate.query(sbSQL.toString(),
				pagination.selectedExtractorGrid, params.toArray());
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Planos entity
	 * 
	 * @param planos
	 *            Planos Bean with the criteria values to filter by.
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, ?> getWhereMap(Planos planos) {

		StringBuilder where = new StringBuilder(
				PlanosDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (planos != null && planos.getIdplano() != null) {
			where.append(" AND t1.IDPLANO = ?");
			params.add(planos.getIdplano());
		}
		if (planos != null && planos.getIdpadre() != null) {
			where.append(" AND t1.IDPADRE = ?");
			params.add(planos.getIdpadre());
		}
		if (planos != null && planos.getIdedificio() != null) {
			where.append(" AND t1.IDEDIFICIO = ?");
			params.add(planos.getIdedificio());
		}
		if (planos != null && planos.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(planos.getIdzona());
		}
		if (planos != null && planos.getIdplanta() != null) {
			where.append(" AND t1.IDPLANTA = ?");
			params.add(planos.getIdplanta());
		}
		if (planos != null && planos.getEjexdesde() != null) {
			where.append(" AND t1.EJEXDESDE = ?");
			params.add(planos.getEjexdesde());
		}
		if (planos != null && planos.getEjeydesde() != null) {
			where.append(" AND t1.EJEYDESDE = ?");
			params.add(planos.getEjeydesde());
		}
		if (planos != null && planos.getEjexhasta() != null) {
			where.append(" AND t1.EJEXHASTA = ?");
			params.add(planos.getEjexhasta());
		}
		if (planos != null && planos.getEjeyhasta() != null) {
			where.append(" AND t1.EJEYHASTA = ?");
			params.add(planos.getEjeyhasta());
		}
		if (planos != null && planos.getBaja() != null) {
			where.append(" AND t1.BAJA = ?");
			params.add(planos.getBaja());
		}
		if (planos != null && planos.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(planos.getFeini());
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Planos entity
	 * 
	 * @param planos
	 *            Planos Bean with the criteria values to filter by.
	 * @param startsWith
	 *            Boolean
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, ?> getWhereLikeMap(Planos planos, Boolean startsWith) {

		StringBuilder where = new StringBuilder(
				PlanosDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (planos != null && planos.getIdplano() != null) {
			where.append(" AND t1.IDPLANO = ?");
			params.add(planos.getIdplano());
		}
		if (planos != null && planos.getIdpadre() != null) {
			where.append(" AND t1.IDPADRE = ?");
			params.add(planos.getIdpadre());
		}
		if (planos != null && planos.getIdedificio() != null) {
			where.append(" AND UPPER(t1.IDEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getIdedificio().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getIdedificio().toUpperCase() + "%");
			}
			where.append(" AND t1.IDEDIFICIO IS NOT NULL");
		}
		if (planos != null && planos.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(planos.getIdzona());
		}
		if (planos != null && planos.getIdplanta() != null) {
			where.append(" AND t1.IDPLANTA = ?");
			params.add(planos.getIdplanta());
		}
		if (planos != null && planos.getEjexdesde() != null) {
			where.append(" AND t1.EJEXDESDE = ?");
			params.add(planos.getEjexdesde());
		}
		if (planos != null && planos.getEjeydesde() != null) {
			where.append(" AND t1.EJEYDESDE = ?");
			params.add(planos.getEjeydesde());
		}
		if (planos != null && planos.getEjexhasta() != null) {
			where.append(" AND UPPER(t1.EJEXHASTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEjexhasta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getEjexhasta().toUpperCase() + "%");
			}
			where.append(" AND t1.EJEXHASTA IS NOT NULL");
		}
		if (planos != null && planos.getEjeyhasta() != null) {
			where.append(" AND t1.EJEYHASTA = ?");
			params.add(planos.getEjeyhasta());
		}
		if (planos != null && planos.getBaja() != null) {
			where.append(" AND UPPER(t1.BAJA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getBaja().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getBaja().toUpperCase() + "%");
			}
			where.append(" AND t1.BAJA IS NOT NULL");
		}
		if (planos != null && planos.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(planos.getFeini());
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Planos entity
	 * 
	 * @param planos
	 *            Planos Bean with the criteria values to filter by.
	 * @param startsWith
	 *            Boolean
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, ?> getWhereObtenerPlanos(Planos planos,
			Boolean startsWith) {

		StringBuilder where = new StringBuilder(
				PlanosDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (planos != null && planos.getIdplano() != null) {
			where.append(" AND t1.IDPLANO = ?");
			params.add(planos.getIdplano());
		}
		if (planos != null && planos.getIdpadre() != null) {
			where.append(" AND t1.IDPADRE = ?");
			params.add(planos.getIdpadre());
		}
		if (planos != null && planos.getIdedificio() != null) {
			where.append(" AND UPPER(t1.IDEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getIdedificio().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getIdedificio().toUpperCase() + "%");
			}
			where.append(" AND t1.IDEDIFICIO IS NOT NULL");
		}
		if (planos != null && planos.getEdificio() != null
				&& planos.getEdificio().getCedificio() != null) {
			where.append(" AND UPPER(t2.CEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEdificio().getCedificio().toUpperCase()
						+ "%");
			} else {
				params.add("%"
						+ planos.getEdificio().getCedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t2.CEDIFICIO IS NOT NULL");
		}
		if (planos != null && planos.getEdificio() != null
				&& planos.getEdificio().getEedificio() != null) {
			where.append(" AND UPPER(t2.EEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEdificio().getEedificio().toUpperCase()
						+ "%");
			} else {
				params.add("%"
						+ planos.getEdificio().getEedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t2.EEDIFICIO IS NOT NULL");
		}

		if (planos != null && planos.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(planos.getIdzona());
		}
		if (planos != null && planos.getZona() != null
				&& planos.getZona().getCzona() != null) {
			where.append(" AND UPPER(t3.CZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getZona().getCzona().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getZona().getCzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t3.CZONA IS NOT NULL");
		}
		if (planos != null && planos.getZona() != null
				&& planos.getZona().getEzona() != null) {
			where.append(" AND UPPER(t3.EZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getZona().getEzona().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getZona().getEzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t3.EZONA IS NOT NULL");
		}

		if (planos != null && planos.getIdplanta() != null) {
			where.append(" AND t1.IDPLANTA = ?");
			params.add(planos.getIdplanta());
		}
		if (planos != null && planos.getPlanta() != null
				&& planos.getPlanta().getCplanta() != null) {
			where.append(" AND UPPER(t4.CPLANTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getPlanta().getCplanta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getPlanta().getCplanta().toUpperCase()
						+ "%");
			}
			where.append(" AND t4.CPLANTA IS NOT NULL");
		}
		if (planos != null && planos.getPlanta() != null
				&& planos.getPlanta().getEplanta() != null) {
			where.append(" AND UPPER(t4.EPLANTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getPlanta().getEplanta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getPlanta().getEplanta().toUpperCase()
						+ "%");
			}
			where.append(" AND t4.EPLANTA IS NOT NULL");
		}

		if (planos != null && planos.getEjexdesde() != null) {
			where.append(" AND t1.EJEXDESDE = ?");
			params.add(planos.getEjexdesde());
		}
		if (planos != null && planos.getEjeydesde() != null) {
			where.append(" AND t1.EJEYDESDE = ?");
			params.add(planos.getEjeydesde());
		}
		if (planos != null && planos.getEjexhasta() != null) {
			where.append(" AND UPPER(t1.EJEXHASTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEjexhasta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getEjexhasta().toUpperCase() + "%");
			}
			where.append(" AND t1.EJEXHASTA IS NOT NULL");
		}
		if (planos != null && planos.getEjeyhasta() != null) {
			where.append(" AND t1.EJEYHASTA = ?");
			params.add(planos.getEjeyhasta());
		}
		if (planos != null && planos.getBaja() != null) {
			where.append(" AND UPPER(t1.BAJA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getBaja().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getBaja().toUpperCase() + "%");
			}
			where.append(" AND t1.BAJA IS NOT NULL");
		}
		if (planos != null && planos.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(planos.getFeini());
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	private Map<String, ?> getWhereObtenerPlanosJerarquia(Planos planos,
			Boolean startsWith) {

		StringBuffer where = new StringBuffer(PlanosDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (planos != null && planos.getIdplano() != null) {
			where.append(" AND t1.IDPLANO = ?");
			params.add(planos.getIdplano());
		}
		if (planos != null && planos.getIdpadre() != null) {
			where.append(" AND t1.IDPADRE = ?");
			params.add(planos.getIdpadre());
		}
		if (planos != null && planos.getIdedificio() != null) {
			where.append(" AND UPPER(t1.IDEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getIdedificio().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getIdedificio().toUpperCase() + "%");
			}
			where.append(" AND t1.IDEDIFICIO IS NOT NULL");
		}
		if (planos != null && planos.getEdificio() != null
				&& planos.getEdificio().getCedificio() != null) {
			where.append(" AND UPPER(t1.CEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEdificio().getCedificio().toUpperCase()
						+ "%");
			} else {
				params.add("%"
						+ planos.getEdificio().getCedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.CEDIFICIO IS NOT NULL");
		}
		if (planos != null && planos.getEdificio() != null
				&& planos.getEdificio().getEedificio() != null) {
			where.append(" AND UPPER(t1.EEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEdificio().getEedificio().toUpperCase()
						+ "%");
			} else {
				params.add("%"
						+ planos.getEdificio().getEedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.EEDIFICIO IS NOT NULL");
		}

		if (planos != null && planos.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(planos.getIdzona());
		}
		if (planos != null && planos.getZona() != null
				&& planos.getZona().getCzona() != null) {
			where.append(" AND UPPER(t1.CZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getZona().getCzona().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getZona().getCzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.CZONA IS NOT NULL");
		}
		if (planos != null && planos.getZona() != null
				&& planos.getZona().getEzona() != null) {
			where.append(" AND UPPER(t1.EZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getZona().getEzona().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getZona().getEzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.EZONA IS NOT NULL");
		}

		if (planos != null && planos.getIdplanta() != null) {
			where.append(" AND t1.IDPLANTA = ?");
			params.add(planos.getIdplanta());
		}
		if (planos != null && planos.getPlanta() != null
				&& planos.getPlanta().getCplanta() != null) {
			where.append(" AND UPPER(t1.CPLANTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getPlanta().getCplanta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getPlanta().getCplanta().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.CPLANTA IS NOT NULL");
		}
		if (planos != null && planos.getPlanta() != null
				&& planos.getPlanta().getEplanta() != null) {
			where.append(" AND UPPER(t1.EPLANTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getPlanta().getEplanta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getPlanta().getEplanta().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.EPLANTA IS NOT NULL");
		}

		if (planos != null && planos.getEjexdesde() != null) {
			where.append(" AND t1.EJEXDESDE = ?");
			params.add(planos.getEjexdesde());
		}
		if (planos != null && planos.getEjeydesde() != null) {
			where.append(" AND t1.EJEYDESDE = ?");
			params.add(planos.getEjeydesde());
		}
		if (planos != null && planos.getEjexhasta() != null) {
			where.append(" AND UPPER(t1.EJEXHASTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getEjexhasta().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getEjexhasta().toUpperCase() + "%");
			}
			where.append(" AND t1.EJEXHASTA IS NOT NULL");
		}
		if (planos != null && planos.getEjeyhasta() != null) {
			where.append(" AND t1.EJEYHASTA = ?");
			params.add(planos.getEjeyhasta());
		}
		if (planos != null && planos.getBaja() != null) {
			where.append(" AND UPPER(t1.BAJA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(planos.getBaja().toUpperCase() + "%");
			} else {
				params.add("%" + planos.getBaja().toUpperCase() + "%");
			}
			where.append(" AND t1.BAJA IS NOT NULL");
		}
		if (planos != null && planos.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(planos.getFeini());
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA

	/**
	 * StringBuilder initilization value
	 */
	public static final int STRING_BUILDER_INIT = 4096;
}
