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.Edificios;
import com.ejie.aa20b.model.Edificiosver;

/**
 * EdificiosverDaoImpl generated by UDA, 13-mar-2015 12:21:16.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class EdificiosverDaoImpl implements EdificiosverDao {
	private JdbcTemplate jdbcTemplate;
	private RowMapper<Edificiosver> rwMap = new RowMapper<Edificiosver>() {
		public Edificiosver mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Edificiosver(resultSet.getString("UIDPER"),
					resultSet.getString("IDEDIFICIO"),
					resultSet.getString("VER"), null);
		}
	};

	private RowMapper<Edificiosver> rwMapEdificiosver = new RowMapper<Edificiosver>() {
		public Edificiosver mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {

			Edificiosver edificiosver = new Edificiosver();

			edificiosver.setUidPer(resultSet.getString("UIDPER"));
			edificiosver.setIdedificio(resultSet.getString("IDEDIFICIO"));
			edificiosver.setVer(resultSet.getString("VER"));

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

			return edificiosver;

		}
	};

	/**
	 * 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 Edificiosver table.
	 * 
	 * @param edificiosver
	 *            Pagination
	 * @return Edificiosver
	 */
	public Edificiosver add(Edificiosver edificiosver) {
		String query = "INSERT INTO EDIFICIOSVER (UID_PER, IDEDIFICIO, VER) VALUES (?,?,?)";
		this.jdbcTemplate.update(query, edificiosver.getUidPer(), edificiosver
				.getIdedificio(), edificiosver.getVer() == null ? "1"
				: edificiosver.getVer());
		return edificiosver;
	}

	/**
	 * Updates a single row in the Edificiosver table.
	 * 
	 * @param edificiosver
	 *            Pagination
	 * @return Edificiosver
	 */
	public Edificiosver update(Edificiosver edificiosver) {
		String query = "UPDATE EDIFICIOSVER SET VER=? WHERE UID_PER=? AND IDEDIFICIO=?";
		this.jdbcTemplate.update(query, edificiosver.getVer(),
				edificiosver.getUidPer(), edificiosver.getIdedificio());
		return edificiosver;
	}

	/**
	 * Finds a single row in the Edificiosver table.
	 * 
	 * @param edificiosver
	 *            Pagination
	 * @return Edificiosver
	 */
	@Transactional(readOnly = true)
	public Edificiosver find(Edificiosver edificiosver) {
		String query = "SELECT t1.UID_PER UIDPER, t1.IDEDIFICIO IDEDIFICIO, t1.VER VER FROM EDIFICIOSVER t1  WHERE t1.UID_PER = ?   AND t1.IDEDIFICIO = ?  ";

		List<Edificiosver> edificiosverList = this.jdbcTemplate.query(query,
				this.rwMap, edificiosver.getUidPer(),
				edificiosver.getIdedificio());
		return (Edificiosver) DataAccessUtils.uniqueResult(edificiosverList);
	}

	/**
	 * Finds a List of rows in the Edificiosver table.
	 * 
	 * @param idUsuario
	 *            Integer
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> obtenerEdificiosUsuarioAsignados(String idUsuario) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.UID_PER UIDPER,t1.IDEDIFICIO IDEDIFICIO,t1.VER VER, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO  ");
		query.append("FROM EDIFICIOSVER t1, EDIFICIOS t2 ");

		StringBuilder where = new StringBuilder(
				" WHERE  t1.IDEDIFICIO=t2.IDEDIFICIO(+) AND t1.UID_PER=? ");
		query.append(where);

		return (List<Edificiosver>) this.jdbcTemplate.query(query.toString(),
				this.rwMapEdificiosver, idUsuario);
	}

	/**
	 * Finds a List of rows in the Edificiosver table.
	 * 
	 * @param idUsuario
	 *            Integer
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> obtenerEdificiosUsuarioLibres(String idUsuario) {
		StringBuilder query = new StringBuilder(
		// "SELECT DISTINCT t2.IDEDIFICIO IDEDIFICIO, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO,  null UIDPER, null VER FROM EDIFICIOS t2 left join  EDIFICIOSVER t1 on  t1.IDEDIFICIO=t2.IDEDIFICIO ");
				"SELECT t1.IDEDIFICIO IDEDIFICIO, t1.CEDIFICIO CEDIFICIO, t1.EEDIFICIO EEDIFICIO, null UIDPER, null VER FROM EDIFICIOS t1 ");

		StringBuilder where = new StringBuilder(
				"  WHERE t1.BAJA='0' AND t1.IDEDIFICIO NOT IN (SELECT DISTINCT t2.IDEDIFICIO FROM EDIFICIOSVER t2 WHERE t2.UID_PER   =?) ORDER BY t1.CEDIFICIO");
		query.append(where);

		return (List<Edificiosver>) this.jdbcTemplate.query(query.toString(),
				this.rwMapEdificiosver, idUsuario);
	}

	/**
	 * Finds a List of rows in the Edificiosver table.
	 * 
	 * @param idUsuario
	 *            Integer
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> obtenerEdificiosUsuarioNOVer(String idUsuario,
			String territorio) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.UID_PER UIDPER,t1.IDEDIFICIO IDEDIFICIO,t1.VER VER, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO  ");
		query.append("FROM EDIFICIOSVER t1, EDIFICIOS t2 ");

		StringBuilder where = new StringBuilder(
				" WHERE  t1.IDEDIFICIO=t2.IDEDIFICIO(+) AND t1.UID_PER=? AND (t1.VER<>1 OR t1.VER is null) ");
		if (territorio != null && !territorio.equals("")) {
			where.append(" AND t2.IDTERRI = ? ");
			where.append(" ORDER BY t2.CEDIFICIO");
			query.append(where);
			return (List<Edificiosver>) this.jdbcTemplate.query(
					query.toString(), this.rwMapEdificiosver, idUsuario,
					territorio);
		} else {
			where.append(" ORDER BY t2.CEDIFICIO");
			query.append(where);
			return (List<Edificiosver>) this.jdbcTemplate.query(
					query.toString(), this.rwMapEdificiosver, idUsuario);
		}

	}

	/**
	 * Finds a List of rows in the Edificiosver table.
	 * 
	 * @param idUsuario
	 *            Integer
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> obtenerEdificiosUsuarioVer(String idUsuario,
			String territorio) {
		StringBuilder query = new StringBuilder(
				"SELECT t2.IDEDIFICIO IDEDIFICIO, t2.CEDIFICIO CEDIFICIO, t2.EEDIFICIO EEDIFICIO,  t1.UID_PER UIDPER, t1.VER VER FROM EDIFICIOS t2 left join  EDIFICIOSVER t1 on  t1.IDEDIFICIO=t2.IDEDIFICIO ");

		StringBuilder where = new StringBuilder(
				"  where t1.UID_PER=? AND t1.VER=1 ");
		if (territorio != null && !territorio.equals("")) {
			where.append(" AND t2.IDTERRI=?");
			where.append(" ORDER BY t2.CEDIFICIO ");
			query.append(where);
			return (List<Edificiosver>) this.jdbcTemplate.query(
					query.toString(), this.rwMapEdificiosver, idUsuario,
					territorio);
		} else {
			where.append(" ORDER BY t2.CEDIFICIO ");
			query.append(where);
			return (List<Edificiosver>) this.jdbcTemplate.query(
					query.toString(), this.rwMapEdificiosver, idUsuario);
		}

	}

	/**
	 * marca el edificio para ver.
	 * 
	 * @param edificiosver
	 *            Edificiosver
	 * @return Edificiosver
	 */
	public Edificiosver marcarVer(Edificiosver edificiosver) {
		String query = "UPDATE EDIFICIOSVER SET VER=1 WHERE UID_PER=? AND IDEDIFICIO=?";
		this.jdbcTemplate.update(query, edificiosver.getUidPer(),
				edificiosver.getIdedificio());
		return edificiosver;
	}

	/**
	 * marca el edificio para NO ver.
	 * 
	 * @param edificiosver
	 *            Edificiosver
	 * @return Edificiosver
	 */
	public Edificiosver marcarNOVer(Edificiosver edificiosver) {
		String query = "UPDATE EDIFICIOSVER SET VER=0 WHERE UID_PER=? AND IDEDIFICIO=?";
		this.jdbcTemplate.update(query, edificiosver.getUidPer(),
				edificiosver.getIdedificio());
		return edificiosver;
	}

	/**
	 * Removes a single row in the Edificiosver table.
	 * 
	 * @param edificiosver
	 *            Pagination
	 * @return
	 */
	public void remove(Edificiosver edificiosver) {
		String query = "DELETE FROM EDIFICIOSVER WHERE UID_PER=? AND IDEDIFICIO=?";
		this.jdbcTemplate.update(query, edificiosver.getUidPer(),
				edificiosver.getIdedificio());
	}

	/**
	 * Finds a List of rows in the Edificiosver table.
	 * 
	 * @param edificiosver
	 *            Edificiosver
	 * @param pagination
	 *            Pagination
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> findAll(Edificiosver edificiosver,
			Pagination pagination) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.UID_PER UIDPER,t1.IDEDIFICIO IDEDIFICIO,t1.VER VER ");
		query.append("FROM EDIFICIOSVER t1 ");

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

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

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(edificiosver);
		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 Edificiosver table using like.
	 * 
	 * @param edificiosver
	 *            Edificiosver
	 * @param pagination
	 *            Pagination
	 * @param startsWith
	 *            Boolean
	 * @return List
	 */
	@Transactional(readOnly = true)
	public List<Edificiosver> findAllLike(Edificiosver edificiosver,
			Pagination pagination, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.UID_PER UIDPER,t1.IDEDIFICIO IDEDIFICIO,t1.VER VER ");
		query.append("FROM EDIFICIOSVER t1 ");

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

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

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

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

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

		if (edificiosver != null && edificiosver.getUidPer() != null) {
			where.append(" AND t1.UID_PER = ?");
			params.add(edificiosver.getUidPer());
		}
		if (edificiosver != null && edificiosver.getIdedificio() != null) {
			where.append(" AND t1.IDEDIFICIO = ?");
			params.add(edificiosver.getIdedificio());
		}
		if (edificiosver != null && edificiosver.getVer() != null) {
			where.append(" AND t1.VER = ?");
			params.add(edificiosver.getVer());
		}

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

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

		if (edificiosver != null && edificiosver.getUidPer() != null) {
			where.append(" AND UPPER(t1.UID_PER) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(edificiosver.getUidPer().toUpperCase() + "%");
			} else {
				params.add("%" + edificiosver.getUidPer().toUpperCase() + "%");
			}
			where.append(" AND t1.UID_PER IS NOT NULL");
		}
		if (edificiosver != null && edificiosver.getIdedificio() != null) {
			where.append(" AND UPPER(t1.IDEDIFICIO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(edificiosver.getIdedificio().toUpperCase() + "%");
			} else {
				params.add("%" + edificiosver.getIdedificio().toUpperCase()
						+ "%");
			}
			where.append(" AND t1.IDEDIFICIO IS NOT NULL");
		}
		if (edificiosver != null && edificiosver.getVer() != null) {
			where.append(" AND UPPER(t1.VER) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(edificiosver.getVer().toUpperCase() + "%");
			} else {
				params.add("%" + edificiosver.getVer().toUpperCase() + "%");
			}
			where.append(" AND t1.VER 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;
}
