package com.lerx.dao.impl;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.lerx.dao.iface.IGroupDao;
import com.lerx.entities.ArticleGroup;
import com.lerx.entities.TempletPortalMain;
import com.lerx.entities.VisitorsBook;
import com.lerx.hql.util.HibernateUtil;
import com.lerx.rank.util.RankUnitUtil;

public class GroupDaoImpl extends HibernateDaoSupport implements IGroupDao {

	@Override
	public long add(ArticleGroup g) {
		VisitorsBook vbook = new VisitorsBook();
		vbook.setObjType(1);
		vbook.setObjTitle(g.getName());
		this.getHibernateTemplate().save(vbook);
		g.setVbook(vbook);
		g = (ArticleGroup) RankUnitUtil.add(this.getHibernateTemplate(), g);
		modifyChanged(g);
		return g.getId();
	}
	
	@Override
	public int modify(ArticleGroup g) {
		TempletPortalMain templet=g.getTemplet();
		if (templet==null) {
			g.setTemplet(null);
		}else {
			g.setTemplet(this.getHibernateTemplate().get(TempletPortalMain.class, templet.getId()));
		}
		int flush=RankUnitUtil.modify(this.getHibernateTemplate(), g);
		
		ArticleGroup changed=findByID(g.getId());
		
		changed.setCh(g.getCh());
		changed.setChanged(g.isChanged());
		changed.setCoerceArt(g.isCoerceArt());
		changed.setCoerceLow(g.isCoerceLow());
		changed.setComm(g.isComm());
		changed.setCw(g.getCw());
		changed.setFolder(g.getFolder());
		changed.setGather(g.isGather());
		changed.setHotn(g.getHotn());
		changed.setHtmlOwn(g.getHtmlOwn());
		changed.setIcoUrl(g.getIcoUrl());
		changed.setImgIntact(g.isImgIntact());
		changed.setIpVisitAllow(g.getIpVisitAllow());
		changed.setJumpToUrl(g.getJumpToUrl());
		changed.setName(g.getName());
		changed.setOpen(g.isOpen());
		changed.setClogging(g.isClogging());
		changed.setPoll(g.isPoll());
		changed.setStaticPage(g.isStaticPage());
		changed.setStatus(g.isStatus());
		if (g.getTemplet()==null || g.getTemplet().getId()<=0) {
			changed.setTemplet(null);
		}else {
			changed.setTemplet(g.getTemplet());
		}
		
		changed.setTitle(g.getTitle());
		changed.setTmp(g.getTmp());
		changed.setUrl(g.getUrl());
		
		this.getHibernateTemplate().update(changed);
		this.getHibernateTemplate().flush();
	
		VisitorsBook vbook = changed.getVbook();
		if (changed!=null && vbook==null) {
			vbook = new VisitorsBook();
			vbook.setObjType(1);
			vbook.setObjTitle(g.getName());
			this.getHibernateTemplate().save(vbook);
			changed.setVbook(vbook);
			this.getHibernateTemplate().update(changed);
		}
		vbook.setObjTitle(changed.getName());
		
		this.getHibernateTemplate().update(vbook);
		modifyChanged(changed);
		this.getHibernateTemplate().flush();
		return flush;
	}
	
	@Override
	public void modifySimple(ArticleGroup g) {
		this.getHibernateTemplate().update(g);
		
	}

	@Override
	public ArticleGroup findByID(long id) {
		return this.getHibernateTemplate().get(ArticleGroup.class, id);
	}
	
	@Override
	public ArticleGroup findByUuid(String uuid) {
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.add(Restrictions.eq("uuid", uuid ) );
		@SuppressWarnings("unchecked")
		List<ArticleGroup> lu = (List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		if (lu.size() > 0) { 
			return lu.get(0);
		}else{
			return null;
		}
	}

	@Override
	public boolean delByID(long id) {
		ArticleGroup g = findByID(id);
		if (g==null) {
			return false;
		}
		modifyChanged(g);
		int r=RankUnitUtil.del(this.getHibernateTemplate(), g);
		if (r<0) {
			return false;
		}else {
			return true;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ArticleGroup> queryByParentID(long parentID,boolean showPosterity,boolean gather,int status) {
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.addOrder(Order.asc("orderStr") );
		criteria.add(Restrictions.eq("deled", false ) );
		
		ArticleGroup parent=findByID(parentID);
		switch (status) {
		case -1:
			criteria.add(Restrictions.eq("status", false ) );
			break;
		case 1:
			criteria.add(Restrictions.eq("status", true ) );
			break;
		default:
		}
		
		if (gather) {
			criteria.add(Restrictions.eq("gather", true ) );
		}
		
		if (parentID > 0L && findByID(parentID)!=null) {
			if (showPosterity) {
//				hql="from ArticleGroup g where g.deled is false and " + statusSql + " g.footLeft > "+parent.getFootLeft() + " and g.footRight < " + parent.getFootRight()+" order by g.orderStr asc";
				criteria.add(Restrictions.gt("footLeft", parent.getFootLeft() ) );
				criteria.add(Restrictions.lt("footRight", parent.getFootRight() ) );
			}else {
				criteria.createAlias("parent", "p"); 
				criteria.add(Restrictions.eq("p.id", parentID ) );
			}
			
		}else {
			
			if (!showPosterity) {
				criteria.add(Restrictions.isNull("parent") );
			}
		}
		
		List<ArticleGroup> list=(List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		
		
		return list;
		
	}
	
	
	@SuppressWarnings("unchecked")
	@Override
	public List<ArticleGroup> queryGatherByParentID(long parentID) {
		
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.addOrder(Order.asc("orderStr") );
		criteria.add(Restrictions.eq("deled", false ) );
		criteria.add(Restrictions.eq("gather", true ) );
		criteria.add(Restrictions.eq("status", true ) );
		
		if (parentID > 0L && findByID(parentID)!=null) {
			criteria.createAlias("parent", "p"); 
			criteria.add(Restrictions.eq("p.id", parentID ) );
			
		}else {
			criteria.add(Restrictions.isNull("parent") );
		}

		List<ArticleGroup> list=(List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		return list;
	}

	@Override
	public HibernateTemplate ht() {
		return this.getHibernateTemplate();
	}

	@Override
	public void move(ArticleGroup g, int offset) {
		modifyChanged(g);
		RankUnitUtil.move(this.getHibernateTemplate(), g, null, offset);
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ArticleGroup> queryParentBySubID(long subID, int status) {
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.add(Restrictions.eq("deled", false ) );
		criteria.addOrder(Order.asc("orderStr") );
		
		ArticleGroup currGroup=findByID(subID);
		switch (status) {
		case -1:
			criteria.add(Restrictions.eq("status", false ) );
			break;
		case 1:
			criteria.add(Restrictions.eq("status", true ) );
			break;
		default:
		}
		
		criteria.add(Restrictions.lt("footLeft", currGroup.getFootLeft() ) );
		criteria.add(Restrictions.gt("footRight", currGroup.getFootRight() ) );
		
		List<ArticleGroup> list=(List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		return list;
		
	}

	@Override
	public void modifyChanged(ArticleGroup g) {
		String hql="update ArticleGroup g set g.changed=true where  g.deled is false and g.footLeft <= "+g.getFootLeft() + " and g.footRight >= " + g.getFootRight();
//		HibernateUtil.executeSql(this.getHibernateTemplate(), HibernateUtil.transHqlToSql(this.getHibernateTemplate(), hql));
		HibernateUtil.executeHql(this.getHibernateTemplate(),hql);
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ArticleGroup> queryChanged() {
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.add(Restrictions.eq("deled", false ) );
		criteria.add(Restrictions.eq("status", true ) );
		criteria.add(Restrictions.eq("open", true ) );
		criteria.add(Restrictions.eq("staticPage", true ) );
		criteria.add(Restrictions.eq("changed", true ) );
		criteria.addOrder(Order.asc("orderStr") );
		
		List<ArticleGroup> list=(List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ArticleGroup> queryAllForStatic() {
		DetachedCriteria criteria=DetachedCriteria.forClass(ArticleGroup.class);
		criteria.add(Restrictions.eq("deled", false ) );
		criteria.add(Restrictions.eq("status", true ) );
		criteria.add(Restrictions.eq("open", true ) );
		criteria.add(Restrictions.eq("staticPage", true ) );
		criteria.addOrder(Order.asc("orderStr") );
		
		List<ArticleGroup> list=(List<ArticleGroup>) this.getHibernateTemplate().findByCriteria(criteria);
		return list;
		
	}

	@Override
	public List<ArticleGroup> findAll() {
		List<ArticleGroup> list = this.getHibernateTemplate().loadAll(ArticleGroup.class);
		return list;
	}


}
