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.TecnicoEdif;
import com.ejie.aa20b.model.Zonas;

/**
 * TecnicoEdifDaoImpl generated by UDA, 22-dic-2014 10:11:52.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class TecnicoEdifDaoImpl implements TecnicoEdifDao {
	private JdbcTemplate jdbcTemplate;
	private RowMapper<TecnicoEdif> rwMap = new RowMapper<TecnicoEdif>() {
		public TecnicoEdif mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {

			TecnicoEdif tecnicoEdif = new TecnicoEdif();
			tecnicoEdif.setIdtecnico(resultSet.getLong("IDTECNICO"));
			tecnicoEdif.setIdedificio(resultSet.getString("IDEDIFICIO"));
			tecnicoEdif.setBaja(resultSet.getString("BAJA"));
			tecnicoEdif.setNombre(resultSet.getString("NOMBRE"));
			tecnicoEdif.setCedificio(resultSet.getString("CEDIFICIO"));
			tecnicoEdif.setEedificio(resultSet.getString("EEDIFICIO"));

			Zonas zona = new Zonas();
			zona.setIdzona(resultSet.getInt("IDZONA"));
			zona.setCzona(resultSet.getString("CZONA") == null ? "" : resultSet
					.getString("CZONA"));
			zona.setEzona(resultSet.getString("EZONA") == null ? "" : resultSet
					.getString("EZONA"));
			tecnicoEdif.setZona(zona);

			return tecnicoEdif;

		}
	};

	/**
	 * 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 TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return TecnicoEdif
	 */
	public TecnicoEdif add(TecnicoEdif tecnicoedif) {
		String query = "INSERT INTO TECNICO_EDIF (IDTECNICO, IDEDIFICIO, BAJA, IDZONA) VALUES (?,?,?,?)";
		this.jdbcTemplate.update(query, tecnicoedif.getIdtecnico(), tecnicoedif
				.getIdedificio(), 0, tecnicoedif.getIdzona() == null ? 0
				: tecnicoedif.getIdzona());
		return tecnicoedif;
	}

	/**
	 * Updates a single row in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return TecnicoEdif
	 */
	public TecnicoEdif update(TecnicoEdif tecnicoedif) {
		String query = "UPDATE TECNICO_EDIF SET BAJA=? WHERE IDTECNICO=? AND IDEDIFICIO=? AND IDZONA=?";
		this.jdbcTemplate.update(query, tecnicoedif.getBaja() == null ? "0"
				: tecnicoedif.getBaja(), tecnicoedif.getIdtecnico(),
				tecnicoedif.getIdedificio(), tecnicoedif.getIdzona());
		return tecnicoedif;
	}

	/**
	 * Finds a single row in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return TecnicoEdif
	 */
	@Transactional(readOnly = true)
	public TecnicoEdif find(TecnicoEdif tecnicoedif) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.IDTECNICO IDTECNICO, t2.NOMBRE NOMBRE, t1.IDEDIFICIO IDEDIFICIO, t3.CEDIFICIO CEDIFICIO,t3.EEDIFICIO EEDIFICIO, t1.BAJA BAJA, t1.IDZONA IDZONA, t4.CZONA CZONA, t4.EZONA EZONA ");
		query.append(" FROM TECNICO_EDIF t1, TECNICOS t2, EDIFICIOS t3, ZONAS t4 ");
		query.append(" WHERE t1.IDTECNICO=t2.IDTECNICO AND t1.IDEDIFICIO =t3.IDEDIFICIO AND t1.IDZONA =t4.IDZONA ");
		query.append(" AND t1.IDTECNICO  = ? AND t1.IDEDIFICIO = ? AND t1.IDZONA = ? ");

		List<TecnicoEdif> tecnicoedifList = this.jdbcTemplate.query(
				query.toString(), this.rwMap, tecnicoedif.getIdtecnico(),
				tecnicoedif.getIdedificio(), tecnicoedif.getIdzona());
		return (TecnicoEdif) DataAccessUtils.uniqueResult(tecnicoedifList);
	}

	/**
	 * Removes a single row in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return
	 */
	public void remove(TecnicoEdif tecnicoedif) {
		String query = "DELETE FROM TECNICO_EDIF WHERE IDTECNICO=? AND IDEDIFICIO=? AND IDZONA=? ";
		this.jdbcTemplate.update(query, tecnicoedif.getIdtecnico(),
				tecnicoedif.getIdedificio(), tecnicoedif.getIdzona());
	}

	/**
	 * Removes a single row in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return
	 */
	public void quitarEdificioATecnico(TecnicoEdif tecnicoedif) {
		String query = "DELETE FROM TECNICO_EDIF WHERE IDTECNICO=? AND IDEDIFICIO=? ";
		this.jdbcTemplate.update(query, tecnicoedif.getIdtecnico(),
				tecnicoedif.getIdedificio());
	}

	/**
	 * Eliminar los tecnicos asociados a un edificio.
	 * 
	 * @param tecnicoedif
	 *            Pagination
	 * @return
	 */
	public void eliminarTecEdif(String idEdificio) {
		String query = "DELETE FROM TECNICO_EDIF WHERE IDEDIFICIO=?";
		this.jdbcTemplate.update(query, idEdificio);
	}

	/**
	 * Finds a List of rows in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            TecnicoEdif
	 * @param pagination
	 *            Pagination
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<TecnicoEdif> findAll(TecnicoEdif tecnicoedif,
			Pagination pagination) {

		StringBuilder query = new StringBuilder(
				"SELECT t1.IDTECNICO IDTECNICO, t2.NOMBRE NOMBRE, t1.IDEDIFICIO IDEDIFICIO, t3.CEDIFICIO CEDIFICIO,t3.EEDIFICIO EEDIFICIO, t1.BAJA BAJA, t1.IDZONA IDZONA, t4.CZONA CZONA, t4.EZONA EZONA ");
		query.append(" FROM TECNICO_EDIF t1, TECNICOS t2, EDIFICIOS t3, ZONAS t4 ");

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

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

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

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

	/**
	 * Finds a List of rows in the TecnicoEdif table.
	 * 
	 * @param idTecnico
	 *            Long
	 * @param idEdificio
	 *            String
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<TecnicoEdif> comprobarTecnicoZonasEdificio(Long idTecnico,
			String idEdificio) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.IDTECNICO IDTECNICO, '' as NOMBRE, t1.IDEDIFICIO IDEDIFICIO, '' as CEDIFICIO,'' as EEDIFICIO, t1.BAJA BAJA, t1.IDZONA IDZONA, '' as CZONA, '' as EZONA "
						+ " FROM TECNICO_EDIF t1 WHERE IDTECNICO="
						+ idTecnico
						+ " AND IDEDIFICIO='" + idEdificio + "' AND IDZONA<>0 ");

		return (List<TecnicoEdif>) this.jdbcTemplate.query(query.toString(),
				this.rwMap);
	}

	/**
	 * Counts rows in the TecnicoEdif table.
	 * 
	 * @param tecnicoedif
	 *            TecnicoEdif
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllCount(TecnicoEdif tecnicoedif) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM TECNICO_EDIF t1, TECNICOS t2, EDIFICIOS t3, ZONAS t4 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(tecnicoedif);
		StringBuilder where = new StringBuilder(
				" WHERE t1.IDTECNICO=t2.IDTECNICO AND t1.IDEDIFICIO =t3.IDEDIFICIO  AND t1.IDZONA =t4.IDZONA ");
		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 TecnicoEdif table using like.
	 * 
	 * @param tecnicoedif
	 *            TecnicoEdif
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<TecnicoEdif> findAllLike(TecnicoEdif tecnicoedif,
			Pagination pagination, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.IDTECNICO IDTECNICO, t2.NOMBRE NOMBRE, t1.IDEDIFICIO IDEDIFICIO, t3.CEDIFICIO CEDIFICIO,t3.EEDIFICIO EEDIFICIO, t1.BAJA BAJA, t1.IDZONA IDZONA, t4.CZONA CZONA, t4.EZONA EZONA ");
		query.append(" FROM TECNICO_EDIF t1, TECNICOS t2, EDIFICIOS t3, ZONAS t4 ");

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

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

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

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

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

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

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

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

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

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

		if (tecnicoedif != null && tecnicoedif.getIdtecnico() != null) {
			where.append(" AND t1.IDTECNICO = ?");
			params.add(tecnicoedif.getIdtecnico());
		}
		if (tecnicoedif != null && tecnicoedif.getIdedificio() != null) {
			where.append(" AND t1.IDEDIFICIO = ?");
			params.add(tecnicoedif.getIdedificio());
		}
		if (tecnicoedif != null && tecnicoedif.getBaja() != null) {
			where.append(" AND t1.BAJA = ?");
			params.add(tecnicoedif.getBaja());
		}
		if (tecnicoedif != null && tecnicoedif.getNombre() != null) {
			where.append(" AND t2.NOMBRE = ?");
			params.add(tecnicoedif.getNombre());
		}
		if (tecnicoedif != null && tecnicoedif.getCedificio() != null) {
			where.append(" AND t3.CEDIFICIO = ?");
			params.add(tecnicoedif.getCedificio());
		}
		if (tecnicoedif != null && tecnicoedif.getCedificio() != null) {
			where.append(" AND t3.EEDIFICIO = ?");
			params.add(tecnicoedif.getCedificio());
		}
		if (tecnicoedif != null && tecnicoedif.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(tecnicoedif.getIdzona());
		}
		if (tecnicoedif != null && tecnicoedif.getZona() != null
				&& tecnicoedif.getZona().getCzona() != null) {
			where.append(" AND t4.CZONA = ?");
			params.add(tecnicoedif.getZona().getCzona());
		}
		if (tecnicoedif != null && tecnicoedif.getZona() != null
				&& tecnicoedif.getZona().getEzona() != null) {
			where.append(" AND t4.EZONA = ?");
			params.add(tecnicoedif.getZona().getEzona());
		}

		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 TecnicoEdif entity
	 * 
	 * @param tecnicoedif
	 *            TecnicoEdif 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(TecnicoEdif tecnicoedif,
			Boolean startsWith) {

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

		if (tecnicoedif != null && tecnicoedif.getIdtecnico() != null) {
			where.append(" AND t1.IDTECNICO = ?");
			params.add(tecnicoedif.getIdtecnico());
		}
		if (tecnicoedif != null && tecnicoedif.getIdedificio() != null) {
			where.append(" AND UPPER(t1.IDEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getIdedificio().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getIdedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.IDEDIFICIO IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getBaja() != null) {
			where.append(" AND UPPER(t1.BAJA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getBaja().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getBaja().toUpperCase() + "%");
			}
			where.append(" AND t1.BAJA IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getNombre() != null) {
			where.append(" AND UPPER(t2.NOMBRE) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getNombre().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getNombre().toUpperCase() + "%");
			}
			where.append(" AND t2.NOMBRE IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getCedificio() != null) {
			where.append(" AND UPPER(t3.CEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getCedificio().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getCedificio().toUpperCase() + "%");
			}
			where.append(" AND t3.CEDIFICIO IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getEedificio() != null) {
			where.append(" AND UPPER(t3.EEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getEedificio().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getEedificio().toUpperCase() + "%");
			}
			where.append(" AND t3.EEDIFICIO IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getIdzona() != null) {
			where.append(" AND t1.IDZONA = ?");
			params.add(tecnicoedif.getIdzona());
		}
		if (tecnicoedif != null && tecnicoedif.getZona() != null
				&& tecnicoedif.getZona().getCzona() != null) {
			where.append(" AND UPPER(t4.CZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getZona().getCzona().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getZona().getCzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t4.CZONA IS NOT NULL");
		}
		if (tecnicoedif != null && tecnicoedif.getZona() != null
				&& tecnicoedif.getZona().getEzona() != null) {
			where.append(" AND UPPER(t4.EZONA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(tecnicoedif.getZona().getEzona().toUpperCase() + "%");
			} else {
				params.add("%" + tecnicoedif.getZona().getEzona().toUpperCase()
						+ "%");
			}
			where.append(" AND t4.EZONA IS NOT NULL");
		}

		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;
}
