package com.ejie.aa20b.dao;

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 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.Zonas;

/**
 * ZonasDaoImpl generated by UDA, 28-nov-2014 11:32:16.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class ZonasDaoImpl implements ZonasDao {
	private JdbcTemplate jdbcTemplate;
	private RowMapper<Zonas> rwMap = new RowMapper<Zonas>() {
		public Zonas mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Zonas(resultSet.getInt("IDZONA"),
					resultSet.getString("CZONA"), resultSet.getString("EZONA"),
					resultSet.getString("RZONA"), resultSet.getString("BAJA"),
					resultSet.getDate("FEINI"));
		}
	};
	private RowMapper<Zonas> rwMapZonas = new RowMapper<Zonas>() {
		public Zonas mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Zonas(resultSet.getInt("IDZONA"),
					resultSet.getString("CZONA"), resultSet.getString("EZONA"),
					null, null, null);
		}
	};

	/**
	 * 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 Zonas table.
	 * 
	 * @param zonas
	 *            Pagination
	 * @return Zonas
	 */
	public Zonas add(Zonas zonas) {

		// Obtener el id correlativo
		Long idCorrelativo = this.jdbcTemplate
				.queryForLong("SELECT ZONA_SEQ.NEXTVAL FROM DUAL");

		String query = "INSERT INTO ZONAS (IDZONA, CZONA, EZONA, RZONA, BAJA, FEINI) VALUES (?,?,?,?,?,?)";
		this.jdbcTemplate.update(query, idCorrelativo, zonas.getCzona(), zonas
				.getEzona(), zonas.getRzona(), zonas.getBaja() == null ? "0"
				: zonas.getBaja(), zonas.getFeini());

		return zonas;
	}

	/**
	 * Updates a single row in the Zonas table.
	 * 
	 * @param zonas
	 *            Pagination
	 * @return Zonas
	 */
	public Zonas update(Zonas zonas) {
		String query = "UPDATE ZONAS SET CZONA=?, EZONA=?, RZONA=?, BAJA=?, FEINI=? WHERE IDZONA=? ";
		this.jdbcTemplate.update(query, zonas.getCzona(), zonas.getEzona(),
				zonas.getRzona(),
				zonas.getBaja() == null ? "0" : zonas.getBaja(),
				zonas.getFeini(), zonas.getIdzona());
		return zonas;
	}

	/**
	 * Finds a single row in the Zonas table.
	 * 
	 * @param zonas
	 *            Pagination
	 * @return Zonas
	 */
	@Transactional(readOnly = true)
	public Zonas find(Zonas zonas) {
		String query = "SELECT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI FROM ZONAS t1  WHERE t1.IDZONA = ? ";

		List<Zonas> zonasList = this.jdbcTemplate.query(query, this.rwMap,
				zonas.getIdzona());
		return (Zonas) DataAccessUtils.uniqueResult(zonasList);
	}

	/**
	 * Finds a single row in the Zonas table.
	 * 
	 * @param zonas
	 *            Pagination
	 * @return Zonas
	 */
	@Transactional(readOnly = true)
	public Zonas obtenerZona(Zonas zonas) {
		String query = "SELECT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI FROM ZONAS t1  WHERE t1.IDZONA = ? ";

		List<Zonas> zonasList = this.jdbcTemplate.query(query, this.rwMap,
				zonas.getIdzona());
		return (Zonas) DataAccessUtils.uniqueResult(zonasList);
	}

	/**
	 * Obtener Zonas para el edificio especificado.
	 * 
	 * @param codEdif
	 *            String
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Zonas> obtenerZonasEdif(String codEdif) {
		StringBuilder query = new StringBuilder(
				"SELECT DISTINCT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI ");
		query.append(" FROM ZONAS t1, EDIF_ESTRUC t2 ");
		query.append(" WHERE t1.IDZONA=t2.IDZONA AND t2.IDEDIFICIO=? ");

		query.append(" ORDER BY t1.IDZONA ");
		return (List<Zonas>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, codEdif);
	}

	@Transactional(readOnly = true)
	public List<Zonas> obtenerZonasEdifAlta(String codEdif) {
		StringBuilder query = new StringBuilder(
				"SELECT DISTINCT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI ");
		query.append(" FROM ZONAS t1, EDIF_ESTRUC t2 ");
		query.append(" WHERE t1.IDZONA=t2.IDZONA AND t2.IDEDIFICIO=? AND t1.SITUACION='A'");

		query.append(" ORDER BY t1.IDZONA ");
		return (List<Zonas>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, codEdif);
	}

	/**
	 * Obtener Zonas para el edificio especificado.
	 * 
	 * @param codEdif
	 *            String
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Zonas> obtenerZonasEdifConPlanos(String codEdif) {
		StringBuilder query = new StringBuilder(
				"SELECT DISTINCT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI ");
		query.append(" FROM ZONAS t1, PLANOS t2 ");
		query.append(" WHERE t1.IDZONA=t2.IDZONA AND t2.IDEDIFICIO=? ");

		query.append(" ORDER BY t1.IDZONA ");
		return (List<Zonas>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, codEdif);
	}

	/**
	 * Removes a single row in the Zonas table.
	 * 
	 * @param zonas
	 *            Pagination
	 * @return
	 */
	public void remove(Zonas zonas) {
		String query = "DELETE FROM ZONAS WHERE IDZONA=? AND CZONA=? AND EZONA=? AND RZONA=? AND BAJA=? AND FEINI=?";
		this.jdbcTemplate.update(query, zonas.getIdzona(), zonas.getCzona(),
				zonas.getEzona(), zonas.getRzona(), zonas.getBaja(),
				zonas.getFeini());
	}

	/**
	 * Finds a List of rows in the Zonas table.
	 * 
	 * @param zonas
	 *            Zonas
	 * @param pagination
	 *            Pagination
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Zonas> findAll(Zonas zonas, Pagination pagination) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDZONA IDZONA,t1.CZONA CZONA,t1.EZONA EZONA,t1.RZONA RZONA,t1.BAJA BAJA,t1.FEINI FEINI ");
		query.append("FROM ZONAS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(zonas);
		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<Zonas>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, params.toArray());
	}

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

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(zonas);
		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 Zonas table using like.
	 * 
	 * @param zonas
	 *            Zonas
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Zonas> findAllLike(Zonas zonas, Pagination pagination,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.IDZONA IDZONA,t1.CZONA CZONA,t1.EZONA EZONA,t1.RZONA RZONA,t1.BAJA BAJA,t1.FEINI FEINI ");
		query.append("FROM ZONAS t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(zonas, 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<Zonas>) this.jdbcTemplate.query(query.toString(),
				this.rwMap, params.toArray());
	}

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

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(zonas, 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());
	}

	/**
	 * Obtiene la lista de zonas
	 * 
	 * @param idZonaSeleccionado
	 * @return
	 */
	public List<Zonas> obtenerZonasEdificioLibres(String codEdificio,
			String language) {

		StringBuffer select = new StringBuffer();
		select.append("SELECT ZO.IDZONA, ZO.CZONA, ZO.EZONA FROM ZONAS ZO WHERE ZO.IDZONA<>0 AND (ZO.BAJA='0' OR ZO.BAJA IS NULL) ");
		select.append(" MINUS ");
		select.append(" SELECT ZO.IDZONA, ZO.CZONA, ZO.EZONA FROM ZONAS ZO, EDIF_ESTRUC ES ");
		select.append(" WHERE ES.IDEDIFICIO=?");
		select.append(" AND ZO.IDZONA=ES.IDZONA AND ZO.SITUACION='A'");

		if (language.equalsIgnoreCase("es"))
			select.append("ORDER BY CZONA");

		else
			select.append("ORDER BY EZONA");

		return (List<Zonas>) this.jdbcTemplate.query(select.toString(),
				this.rwMapZonas, codEdificio);

	}

	/**
	 * Obtiene la lista de zonas de un edificio que no estan asignadas a un
	 * técnico
	 * 
	 * @param codEdificio
	 *            String
	 * @param idTecnico
	 *            Long
	 * @param language
	 *            String
	 * @return List
	 */
	public List<Zonas> buscaZonasEdificioTecnicoLibres(String codEdificio,
			Long idTecnico, String language) {

		StringBuffer select = new StringBuffer();

		select.append("SELECT ZO.IDZONA, ZO.CZONA, ZO.EZONA ");
		select.append("FROM ZONAS ZO, EDIF_ESTRUC ES ");
		select.append("WHERE ZO.IDZONA=ES.IDZONA AND (ZO.BAJA='0' OR ZO.BAJA  IS NULL) and  ES.IDEDIFICIO=? ");
		select.append("MINUS ");
		select.append("SELECT ZO.IDZONA, ZO.CZONA, ZO.EZONA  ");
		select.append("FROM ZONAS ZO, TECNICO_EDIF TE ");
		select.append("WHERE ZO.IDZONA=TE.IDZONA AND TE.IDEDIFICIO=? AND te.idtecnico=? ");

		if (language.equalsIgnoreCase("es"))
			select.append("ORDER BY CZONA");

		else
			select.append("ORDER BY EZONA");

		return (List<Zonas>) this.jdbcTemplate.query(select.toString(),
				this.rwMapZonas, codEdificio, codEdificio, idTecnico);

	}

	/**
	 * Obtiene la lista de zonas de un edificio que estan asignadas a un técnico
	 * 
	 * @param codEdificio
	 *            String
	 * @param idTecnico
	 *            Long
	 * @param language
	 *            String
	 * @return List
	 */
	public List<Zonas> buscaZonasEdificioTecnicoOcupadas(String codEdificio,
			Long idTecnico, String language) {

		StringBuffer select = new StringBuffer();

		select.append("SELECT ZO.IDZONA, ZO.CZONA, ZO.EZONA  ");
		select.append("FROM ZONAS ZO, TECNICO_EDIF TE ");
		select.append("WHERE ZO.IDZONA=TE.IDZONA AND ZO.IDZONA<>0 AND TE.IDEDIFICIO=? AND te.idtecnico=? ");

		if (language.equalsIgnoreCase("es"))
			select.append("ORDER BY CZONA");

		else
			select.append("ORDER BY EZONA");

		return (List<Zonas>) this.jdbcTemplate.query(select.toString(),
				this.rwMapZonas, codEdificio, idTecnico);

	}

	/**
	 * Obtiene la lista de zonas
	 * 
	 * @param idZonaSeleccionado
	 * @return
	 */
	public List<Zonas> obtenerZonasEdificioOcupadas(String codEdificio,
			String language) {

		StringBuffer select = new StringBuffer();
		select.append("SELECT DISTINCT ZO.IDZONA, ZO.CZONA, ZO.EZONA FROM ZONAS ZO, EDIF_ESTRUC ES ");
		select.append(" WHERE ES.IDEDIFICIO=? ");
		select.append(" AND ZO.IDZONA=ES.IDZONA AND ZO.SITUACION='A'");

		if (language.equalsIgnoreCase("es"))
			select.append(" ORDER BY ZO.CZONA");
		else
			select.append(" ORDER BY ZO.EZONA");

		return (List<Zonas>) this.jdbcTemplate.query(select.toString(),
				this.rwMapZonas, codEdificio);

	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Zonas entity
	 * 
	 * @param zonas
	 *            Zonas 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(Zonas zonas) {

		StringBuilder where = new StringBuilder(
				ZonasDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();
		where.append(" AND t1.SITUACION = 'A' ");
		if (zonas != null && zonas.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(zonas.getIdzona());
		}
		if (zonas != null && zonas.getCzona() != null) {
			where.append(" AND t1.CZONA = ?");
			params.add(zonas.getCzona());
		}
		if (zonas != null && zonas.getEzona() != null) {
			where.append(" AND t1.EZONA = ?");
			params.add(zonas.getEzona());
		}
		if (zonas != null && zonas.getRzona() != null) {
			where.append(" AND t1.RZONA = ?");
			params.add(zonas.getRzona());
		}
		if (zonas != null && zonas.getBaja() != null) {
			where.append(" AND t1.BAJA = ?");
			params.add(zonas.getBaja());
		}
		if (zonas != null && zonas.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(zonas.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 Zonas entity
	 * 
	 * @param zonas
	 *            Zonas 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(Zonas zonas, Boolean startsWith) {

		StringBuilder where = new StringBuilder(
				ZonasDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();
		where.append(" AND t1.SITUACION = 'A' ");
		if (zonas != null && zonas.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(zonas.getIdzona());
		}
		if (zonas != null && zonas.getCzona() != null) {
			where.append(" AND UPPER(t1.CZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(zonas.getCzona().toUpperCase() + "%");
			} else {
				params.add("%" + zonas.getCzona().toUpperCase() + "%");
			}
			where.append(" AND t1.CZONA IS NOT NULL");
		}
		if (zonas != null && zonas.getEzona() != null) {
			where.append(" AND UPPER(t1.EZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(zonas.getEzona().toUpperCase() + "%");
			} else {
				params.add("%" + zonas.getEzona().toUpperCase() + "%");
			}
			where.append(" AND t1.EZONA IS NOT NULL");
		}
		if (zonas != null && zonas.getRzona() != null) {
			where.append(" AND UPPER(t1.RZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(zonas.getRzona().toUpperCase() + "%");
			} else {
				params.add("%" + zonas.getRzona().toUpperCase() + "%");
			}
			where.append(" AND t1.RZONA IS NOT NULL");
		}
		if (zonas != null && zonas.getBaja() != null) {
			where.append(" AND UPPER(t1.BAJA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(zonas.getBaja().toUpperCase() + "%");
			} else {
				params.add("%" + zonas.getBaja().toUpperCase() + "%");
			}
			where.append(" AND t1.BAJA IS NOT NULL");
		}
		if (zonas != null && zonas.getFeini() != null) {
			where.append(" AND t1.FEINI = ?");
			params.add(zonas.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;

	@Transactional(readOnly = true)
	public Zonas obtenerZonaDesdeXlnets(Zonas zonas) {
		String query = "SELECT t1.IDZONA IDZONA, t1.CZONA CZONA, t1.EZONA EZONA, t1.RZONA RZONA, t1.BAJA BAJA, t1.FEINI FEINI FROM ZONAS t1  WHERE t1.CODZONA = ? AND t1.SITUACION='A'  ";

		List<Zonas> zonasList = this.jdbcTemplate.query(query, this.rwMap,
				zonas.getCodZona());

		/*
		 * if (zonasList != null && zonasList.size() > 1) { return
		 * zonasList.get(0); } else {
		 */
		return (Zonas) DataAccessUtils.uniqueResult(zonasList);
		// }
	}
}
