package com.olmedos.dao;

import com.olmedos.util.HibernateUtil;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public abstract class AbstractDao {

    public void save(Object entity) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        s.save(entity);
        tx.commit();
        s.close();

    }

    public void update(Object entity) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        s.update(entity);
        tx.commit();
        s.close();

    }

    public void delete(Object entity) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        s.delete(entity);
        tx.commit();
        s.close();

    }

    public Object getById(Serializable id) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Object entity = s.get(getEntity(), id);
        tx.commit();
        s.close();
        return entity;

    }

    public List<?> getAll() {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName()).list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByLike(String campo, String dato) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        List lista = cr.add(Restrictions.like(campo, dato + "%")).list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByField(String campo, Object dato) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        List lista = cr.add(Restrictions.eq(campo, dato)).list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByTwoField(String campo1, Object dato1,
            String campo2, Object dato2) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo1, dato1));
        cr.add(Restrictions.eq(campo2, dato2));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByFieldOrderAsc(String campo, Object dato,
            String campoOrden) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo, dato));
        cr.addOrder(Order.asc(campoOrden));
        tx.commit();
        List lista = cr.list();
        s.close();
        return lista;

    }

    public List<?> getByOrderAsc(String campoOrden) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.addOrder(Order.asc(campoOrden));
        tx.commit();
        List lista = cr.list();
        s.close();
        return lista;

    }

    public List<?> getByOrderDesc(String campoOrden) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.addOrder(Order.desc(campoOrden));
        tx.commit();
        List lista = cr.list();
        s.close();
        return lista;

    }

    public List<?> getByFieldOrderDesc(String campo, Object dato,
            String campoOrden) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo, dato));
        cr.addOrder(Order.desc(campoOrden));
        tx.commit();
        List lista = cr.list();
        s.close();
        return lista;

    }

    public List<?> getByTwoFieldOrderDesc(String campo1, Object dato1,
            String campo2, Object dato2, String campoOrden) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo1, dato1));
        cr.add(Restrictions.eq(campo2, dato2));
        cr.addOrder(Order.desc(campoOrden));
        tx.commit();
        List lista = cr.list();
        s.close();
        return lista;

    }

    public List<?> getByLikeGroup(String campo1, String dato1,
            String campo2, boolean dato2, String campoGroupBy) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.like(campo1, dato1 + "%"));
        cr.add(Restrictions.eq(campo2, dato2));
        cr.setProjection(Projections.projectionList()
                .add(Projections.groupProperty(campoGroupBy)));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByLikeGroup(
            String campo1, String dato1, String campoGroupBy) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.like(campo1, dato1 + "%"));
        cr.setProjection(Projections.projectionList()
                .add(Projections.groupProperty(campoGroupBy)));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public long getByFieldSum(
            String campo, Object dato, String campoSum) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo, dato));
        cr.setProjection(Projections.sum(campoSum));
        List lista = cr.list();
        tx.commit();
        s.close();
        try {
            return (long) lista.get(0);
        } catch (Exception e) {
            return 0;
        }

    }

    public List<?> getByGroupByAll(String campoGroupBy, String campo) {

        /* Session s = HibernateUtil.getSessionFactory().openSession();
         Transaction tx = s.beginTransaction();
         List lista = s.createQuery("FROM " + getEntity().getName() + " GROUP BY "
         + campoGroupBy).list();
         tx.commit();
         s.close();
         return lista;*/
        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        //cr.add(Restrictions.gt(campo, 0l));
        cr.setProjection(Projections.groupProperty(campoGroupBy));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByTwoFieldDistinct(String campo1, Object dato1,
            String campo2, Object dato2) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo1, dato1));
        cr.add(Restrictions.ne(campo2, dato2));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByThreeField(String campo1, Object dato1,
            String campo2, Object dato2, String campo3, Object dato3) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo1, dato1));
        cr.add(Restrictions.eq(campo2, dato2));
        cr.add(Restrictions.eq(campo3, dato3));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByThreeFieldOR(String campo1, Object dato1,
            String campo2, Object dato2, String campo3, Object dato3) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.eq(campo1, dato1));
        cr.add(Restrictions.or(Restrictions.eq(campo2, dato2),
                Restrictions.eq(campo3, dato3)));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByTwoFieldOR(String campo1, Object dato1,
            String campo2, Object dato2) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        Criteria cr = s.createCriteria(getEntity().getName());
        cr.add(Restrictions.or(Restrictions.eq(campo1, dato1),
                Restrictions.eq(campo2, dato2)));
        List lista = cr.list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByOneField(String campo1, long dato1) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo1 + " = " + dato1 + ")")
                .list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByTwoField2(String campo1, long dato1,
            String campo2, Object dato2) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo1 + " = " + dato1 + ") AND (" + campo2 + " = " + dato2 + ")")
                .list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByThreeField(String campo1, long dato1,
            String campo2, Object dato2, String campo3, Object dato3) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo1 + " = " + dato1 + ") AND (" + campo2 + " = " + dato2 + ") AND (" + campo3 + " = " + dato3 + ")")
                .list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByGroupBy(String campo, int dato, String campoGroupBy) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo + " = " + dato + ") GROUP BY " + campoGroupBy).list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByGroupBy(String campo1, String dato1,
            String campo2, int dato2, String campoGroupBy) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo1 + " LIKE '" + dato1 + "%') AND (" + campo2
                + " = " + dato2 + ") GROUP BY " + campoGroupBy).list();
        tx.commit();
        s.close();
        return lista;

    }

    public List<?> getByGroupBy(String campo1, int dato1,
            String campo2, int dato2, String campoGroupBy) {

        Session s = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = s.beginTransaction();
        List lista = s.createQuery("FROM " + getEntity().getName() + " WHERE ("
                + campo1 + " LIKE " + dato1 + "%) AND ("
                + campo2 + " = " + dato2 + ") GROUP BY "
                + campoGroupBy).list();
        tx.commit();
        s.close();
        return lista;

    }
    
    public abstract Class getEntity();
}
