//$Id: PraceAction.java,v 1.7 2007/11/30 15:30:21 xvymv01 Exp $
package cz.triangle.dostal.prace.action;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import struts.HibernatePlugIn;
import cz.triangle.dostal.prace.Prace;
import cz.triangle.dostal.prace.Ukol;
import cz.triangle.dostal.prace.ZmenenaPrace;
import cz.triangle.dostal.prace.form.DatumForm;
import cz.triangle.dostal.prace.form.PraceForm;
import cz.triangle.dostal.prace.form.VyberUzivatelForm;
import cz.triangle.dostal.trzby.Uzivatel;

public class PraceAction extends DispatchAction {

	public static String SUCCESS = "vypis";
	public static String CHYBA = "chyba";
	public static String AKCE = "akce";
	public static String AKCE_PO_ODESLANI = "akce_po_odeslani";

	public ActionForward execute(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response)
		throws Exception {

		ActionForward forward = null;

		forward = super.execute(mapping, form, request, response);

		vypis(mapping, form, request, response);

		return forward;

	}

	public ActionForward novy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

		request.setAttribute(AKCE_PO_ODESLANI, "zapsatnovy");

		return mapping.findForward(SUCCESS);
	}

	public ActionForward smazat(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

		Session hsess = HibernatePlugIn.sessionFactory(request).openSession();
		Transaction tx = null;
		try {
			tx = hsess.beginTransaction();
			String id_string = request.getParameter("id");
			Prace polozka = (Prace) hsess.load(Prace.class, new Long(id_string));
			hsess.delete(polozka);
			tx.commit();
			request.setAttribute(AKCE_PO_ODESLANI, "zapsat");
			request.setAttribute("id", polozka.getId());
		} catch (HibernateException e) {
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
			if (tx != null)
				tx.rollback();
		} catch (Exception e) {
			request.setAttribute(CHYBA, "Napodařilo se smazat.");
		} finally {
			hsess.close();
		}

		return mapping.findForward(SUCCESS);
	}

	public ActionForward zapsatnovy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
		throws Exception {

		HttpSession httpSession = request.getSession();
		if (httpSession.isNew()){
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
			return mapping.findForward(SUCCESS);
		}
		Session hsess = HibernatePlugIn.sessionFactory(request).openSession();
		Transaction tx = null;
		try {
			tx = hsess.beginTransaction();
			PraceForm polozkaForm = (PraceForm) form;
			Prace polozka = new Prace();

			//zjisteni uzivatel
			/*
			String uzivJmeno = request.getRemoteUser();
			List uzivateleList = session.find("from Uzivatel as uzivatel where uzivatel.uzivJmeno=?", uzivJmeno, Hibernate.STRING);
			Uzivatel uzivatel = (Uzivatel) uzivateleList.get(0);
			*/
			Uzivatel uzivatel = (Uzivatel) httpSession.getAttribute("uzivatel");
			
			Ukol ukol = (Ukol) hsess.load(Ukol.class, polozkaForm.getId_ukol());

			DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, new Locale("cs", "CZ"));
			Date datum = null;
			String s_datum;
			datum = (Date) httpSession.getAttribute("datum");
			if (datum == null) {
				s_datum = request.getParameter("datum");
				if ((s_datum != null) && (!s_datum.trim().equalsIgnoreCase(""))) {
					datum = dateFormat.parse(s_datum);
				}
			}
			if (datum == null) {
				datum = new Date();
			}
			SimpleDateFormat casFormat = new SimpleDateFormat("HH:mm");
			Calendar casOd = Calendar.getInstance();
			casOd.setTime(datum);
			Calendar casOdHod = Calendar.getInstance();
			casOdHod.setTime(casFormat.parse(polozkaForm.getCasOd()));
			casOd.set(Calendar.HOUR_OF_DAY, casOdHod.get(Calendar.HOUR_OF_DAY));
			casOd.set(Calendar.MINUTE, casOdHod.get(Calendar.MINUTE));
			casOd.set(Calendar.SECOND, 0);
			casOd.set(Calendar.MILLISECOND, 0);

			Calendar casDo = Calendar.getInstance();
			casDo.setTime(datum);
			Calendar casDoHod = Calendar.getInstance();
			casDoHod.setTime(casFormat.parse(polozkaForm.getCasDo()));
			casDo.set(Calendar.HOUR_OF_DAY, casDoHod.get(Calendar.HOUR_OF_DAY));
			casDo.set(Calendar.MINUTE, casDoHod.get(Calendar.MINUTE));
			casDo.set(Calendar.SECOND, 0);
			casDo.set(Calendar.MILLISECOND, 0);
			if ((casDoHod.get(Calendar.HOUR_OF_DAY) == 0) && (casDoHod.get(Calendar.MINUTE) == 0))
				casDo.set(Calendar.DAY_OF_YEAR, casDo.get(Calendar.DAY_OF_YEAR) + 1);

			polozka.setCasOd(casOd.getTime());
			/* jestlize je zaskrtnuto, ze se ma zapsat pouze
			 * prichod do konecneho casu se zapise pocatecni
			 */
			if ((polozkaForm.getPouze_prichod()!=null) && (polozkaForm.getPouze_prichod().equalsIgnoreCase("ano"))){
				polozka.setCasDo(casOd.getTime());
			}else{
				polozka.setCasDo(casDo.getTime());
			}
			polozka.setId_uzivatel(uzivatel.getId());
			polozka.setPopis(polozkaForm.getPopis());
			polozka.setUkol(ukol);

			//jestlize existuje polozka se stejnym casem od a do, lze vlozit polozku se starsim datem
			List stejne = hsess.find("from Prace as prace where prace.casOd=prace.casDo and prace.id_uzivatel="+uzivatel.getId());
			if (stejne.size()>0){
				if (stejne.size()>1){
					throw new Exception("Snaha o vlozeni nove prace, ale v tabulce PRACE je vice jak jeden zaznam cas_od=cas_do");
				}
				if (stejne.size()==1){
					Prace stejna = (Prace) stejne.get(0);
					if (stejna.getCasOd().before(polozka.getCasDo())){
						Exception e = new Exception("Snaha o vlozeni nove prace, kdyz exstuje predchozi cas_od=cas_do");
						throw e;
					}
				}
			}
			polozka.setSkutecOd(polozka.getCasOd());
			polozka.setSkutecDo(polozka.getCasDo());
			hsess.save(polozka);
			
			//zaznamenam operaci do bonzacke tabulky
			Locale locale = new Locale("cs");
			DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
			DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
			StringBuffer sb = new StringBuffer("nový: ");
			sb.append(df.format(polozka.getCasOd())+" ");
			sb.append(tf.format(polozka.getCasOd())+"-"+tf.format(polozka.getCasDo()));
			sb.append(" "+polozka.getUkol().getDlouhyNazev());
			ZmenenaPrace zp = new ZmenenaPrace();
			zp.setPoznamka(sb.toString());
			zp.setPrace(polozka);
			zp.setUzivatel(uzivatel);
			zp.setCas(new Date());
			hsess.save(zp);
			
			tx.commit();
			request.setAttribute(AKCE_PO_ODESLANI, "zapsat");
		} catch (HibernateException e) {
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
			if (tx != null)
				tx.rollback();
		} catch (Exception e) {
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny. "+e.getMessage());
		} finally {
			hsess.close();
		}

		return mapping.findForward(SUCCESS);
	}

	public ActionForward zapsat(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

		HttpSession httpSession = request.getSession();
		if (httpSession.isNew()){
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
			return mapping.findForward(SUCCESS);
		}
		Session hsess = HibernatePlugIn.sessionFactory(request).openSession();
		Transaction tx = null;
		try {
			tx = hsess.beginTransaction();
			PraceForm polozkaForm = (PraceForm) form;
			String id_string = request.getParameter("id");
			Prace polozka = (Prace) hsess.load(Prace.class, new Long(id_string));
			
			Date oldOd = polozka.getCasOd();
			Date oldDo = polozka.getCasDo();

			//zjisteni uzivatel
			Uzivatel uzivatel = (Uzivatel) httpSession.getAttribute("uzivatel");

			Ukol ukol = (Ukol) hsess.load(Ukol.class, polozkaForm.getId_ukol());

			DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, new Locale("cs", "CZ"));
			Date datum = null;
			String s_datum;
			datum = (Date) httpSession.getAttribute("datum");
			if (datum == null) {
				s_datum = request.getParameter("datum");
				if ((s_datum != null) && (!s_datum.trim().equalsIgnoreCase(""))) {
					datum = dateFormat.parse(s_datum);
				}
			}
			if (datum == null) {
				datum = new Date();
			}
			SimpleDateFormat casFormat = new SimpleDateFormat("HH:mm");
			Calendar casOd = Calendar.getInstance();
			casOd.setTime(datum);
			Calendar casOdHod = Calendar.getInstance();
			casOdHod.setTime(casFormat.parse(polozkaForm.getCasOd()));
			casOd.set(Calendar.HOUR_OF_DAY, casOdHod.get(Calendar.HOUR_OF_DAY));
			casOd.set(Calendar.MINUTE, casOdHod.get(Calendar.MINUTE));
			casOd.set(Calendar.SECOND, 0);
			casOd.set(Calendar.MILLISECOND, 0);

			Calendar casDo = Calendar.getInstance();
			casDo.setTime(datum);
			Calendar casDoHod = Calendar.getInstance();
			casDoHod.setTime(casFormat.parse(polozkaForm.getCasDo()));
			casDo.set(Calendar.HOUR_OF_DAY, casDoHod.get(Calendar.HOUR_OF_DAY));
			casDo.set(Calendar.MINUTE, casDoHod.get(Calendar.MINUTE));
			casDo.set(Calendar.SECOND, 0);
			casDo.set(Calendar.MILLISECOND, 0);
			if ((casDoHod.get(Calendar.HOUR_OF_DAY) == 0) && (casDoHod.get(Calendar.MINUTE) == 0))
				casDo.set(Calendar.DAY_OF_YEAR, casDo.get(Calendar.DAY_OF_YEAR) + 1);

			polozka.setCasOd(casOd.getTime());
			polozka.setCasDo(casDo.getTime());
			polozka.setId_uzivatel(uzivatel.getId());
			polozka.setPopis(polozkaForm.getPopis());
			polozka.setUkol(ukol);
			polozka.setId(new Long(id_string));
			//jestlize existuje polozka se stejnym casem od a do, lze vlozit polozku se starsim datem
			List stejne = hsess.find("from Prace as prace where prace.casOd=prace.casDo and prace.id_uzivatel="+uzivatel.getId());
			if (stejne.size()>0){
				if (stejne.size()>1){
					throw new Exception("Snaha o vlozeni nove prace, ale v tabulce PRACE je vice jak jeden zaznam cas_od=cas_do");
				}
				if (stejne.size()==1){
					Prace stejna = (Prace) stejne.get(0);
					if (stejna.getCasOd().before(polozka.getCasDo())){
						Exception e = new Exception("Snaha o vlozeni nove prace, kdyz exstuje predchozi cas_od=cas_do");
						throw e;
					}
				}
			}
			polozka.setSkutecOd(polozka.getCasOd());
			polozka.setSkutecDo(polozka.getCasDo());
			hsess.update(polozka);
			
			//zaznamenam operaci do bonzacke tabulky
			Locale locale = new Locale("cs");
			DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
			DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
			StringBuffer sb = new StringBuffer("úprava: ");
			sb.append(df.format(oldOd)+" ");
			sb.append(tf.format(oldOd)+"-"+tf.format(oldDo));
			sb.append(" -> ");
			sb.append(tf.format(polozka.getCasOd())+"-"+tf.format(polozka.getCasDo()));
			sb.append(" "+polozka.getUkol().getDlouhyNazev());
			ZmenenaPrace zp = new ZmenenaPrace();
			zp.setPoznamka(sb.toString());
			zp.setPrace(polozka);
			zp.setUzivatel(uzivatel);
			zp.setCas(new Date());
			hsess.save(zp);
			tx.commit();
			request.setAttribute(AKCE_PO_ODESLANI, "zapsat");
		} catch (HibernateException e) {
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
			if (tx != null)
				tx.rollback();
		} catch (Exception e) {
			request.setAttribute(CHYBA, "Napodařilo se zapsat změny.");
		} finally {
			hsess.close();
		}
		return mapping.findForward(SUCCESS);
	}

	public ActionForward vypis(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		Session hsess = HibernatePlugIn.sessionFactory(request).openSession();
		Transaction tx = null;
		try {
			tx = hsess.beginTransaction();
			HttpSession httpSession = request.getSession();
			String archiv = (String) httpSession.getAttribute("archiv");
			
			//jestlize je admin nacteni uzivatelu
			if (request.isUserInRole("admin")){
				List uzivatele = null; 
				if ((archiv!=null) && (archiv.equalsIgnoreCase("ano"))){
					uzivatele = hsess.find("from Uzivatel as uzivatel where uzivatel.konec<? and (uzivatel.skryty<>true or uzivatel.skryty is null) order by uzivatel.prijmeni, uzivatel.jmeno", new Date(), Hibernate.DATE);
				}
				else{
					uzivatele = hsess.find("from Uzivatel as uzivatel where uzivatel.konec>=? and (uzivatel.skryty<>true or uzivatel.skryty is null) order by uzivatel.prijmeni, uzivatel.jmeno", new Date(), Hibernate.DATE);
				}
				request.setAttribute("uzivatele", uzivatele);
				request.setAttribute("admin", new Boolean(true));			
			}
			else{
				request.setAttribute("admin", new Boolean(false));			
			}
			//zjisteni uzivatel
			String uzivJmeno = request.getRemoteUser();
			List uzivateleList = hsess.find("from Uzivatel as uzivatel where uzivatel.uzivJmeno=?", uzivJmeno, Hibernate.STRING);
			Uzivatel uzivatel = (Uzivatel) uzivateleList.get(0);
			//jestlize jsem administrator - uzivatel je vybrany
			if (request.isUserInRole("admin")){
				Uzivatel vybranyUzivatel = (Uzivatel) httpSession.getAttribute("uzivatel");
				if (vybranyUzivatel!=null){
					uzivatel = vybranyUzivatel;
					uzivatel = (Uzivatel) hsess.load(Uzivatel.class, uzivatel.getId());				
				}
				VyberUzivatelForm uzivForm = new VyberUzivatelForm();
				uzivForm.setId_uzivatel(uzivatel.getId());
				uzivForm.setNavrat("prace");
				request.setAttribute("vyberUzivatelForm", uzivForm);
			}
			httpSession.setAttribute("uzivatel", uzivatel);

			//zjisteni datumu
			DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, new Locale("cs", "CZ"));
			Date datum = null;
			String s_datum;
			datum = (Date) httpSession.getAttribute("datum");
/*
			if (datum == null) {
				s_datum = request.getParameter("datum");
				if ((s_datum != null) && (!s_datum.trim().equalsIgnoreCase(""))) {
					datum = dateFormat.parse(s_datum);
				}
			}
*/
			if (datum == null) {
				datum = new Date();
			}
			Calendar datumC = Calendar.getInstance();
			datumC.setTime(datum);
			String den = String.valueOf(datumC.get(Calendar.DAY_OF_MONTH));
			String mesic = String.valueOf(datumC.get(Calendar.MONTH) + 1);
			String rok = String.valueOf(datumC.get(Calendar.YEAR));
			httpSession.setAttribute("datum", datum);
			// zjisteni, zda jiz neni pozde na zmenu mesice pro neadministratory
			Calendar dnesCal = Calendar.getInstance();
			Calendar nastavenyCal = Calendar.getInstance();
			nastavenyCal.setTime(datum);
			if ((nastavenyCal.get(Calendar.MONTH)!=dnesCal.get(Calendar.MONTH)) || (nastavenyCal.get(Calendar.YEAR)!=dnesCal.get(Calendar.YEAR))){
				request.setAttribute("konec_editace","ano");
			}
			DatumForm f2 = new DatumForm();
			f2.setDatum(dateFormat.format(datum));
			f2.setNavrat("prace");
			request.setAttribute("datumForm", f2);

			//nacteni ukolu
			List ukoly = hsess.find("from Ukol as ukol");
			request.setAttribute("ukoly", ukoly);

			// nacteni polozek PostgreSQL
					Query sqlQuery =
						hsess.createSQLQuery(
							"select {prace.*} from prace {prace} where id_uzivatel="
								+ uzivatel.getId()
								+ " and EXTRACT(DAY FROM casod)="
								+ den
								+ " and EXTRACT(month FROM casdo)="
								+ mesic
								+ " and EXTRACT(year FROM casod)="
								+ rok
								+ " order by casod",
							"prace",
							Prace.class);
			// HSQL
/*
			Query sqlQuery =
				hsess.createSQLQuery(
					"select {prace.*} from prace {prace} where id_uzivatel="
						+ uzivatel.getId()
						+ " and DAYOFMONTH(casod)="
						+ den
						+ " and MONTH(casdo)="
						+ mesic
						+ " and YEAR(casod)="
						+ rok
						+ " order by casod",
					"prace",
					Prace.class);
*/
			List polozky = sqlQuery.list();
			request.setAttribute("polozky", polozky);
			Prace posledniPolozka = null;
			String posledniCasDo = "00:00";
			if (polozky.size() > 0) {
				posledniPolozka = (Prace) polozky.get(polozky.size() - 1);
				posledniCasDo = posledniPolozka.getCasDoHod();
			}
			if (posledniCasDo.equalsIgnoreCase("24:00")) {
				posledniCasDo = "00:00";
			}
			request.setAttribute("posledniCasDo", posledniCasDo);
			String akce = request.getParameter(AKCE);
			// po vkladani noveho, opet vkladam novy
			if ((akce != null) && (akce.equalsIgnoreCase("zapsatnovy"))) {
				request.setAttribute(AKCE_PO_ODESLANI, "zapsatnovy");
				request.setAttribute("praceForm", null);
				return mapping.findForward(SUCCESS);
			}

			if (!((akce != null) && (akce.equalsIgnoreCase("novy")))) {
				if (polozky.isEmpty()) {
					request.setAttribute(AKCE_PO_ODESLANI, "zapsatnovy");
					return mapping.findForward(SUCCESS);
				} else {
					request.setAttribute(AKCE_PO_ODESLANI, "zapsat");
				}
			}

			// zjisteni aktualni vybraneho prvku
			// id predano ze stranky		
			String id_string = request.getParameter("id");
			Long id_long = null;

			// id nebylo predano - mozna byla vlozena nova polozka
			if (((id_string != null) && (id_string.length() == 0)) || (id_string == null)) {
				id_long = (Long) request.getAttribute("id");
			} else {
				// id bylo predano ze stranky - rozparsuju ho
				try {
					id_long = new Long(id_string);
				} catch (NumberFormatException e) {
					request.setAttribute(CHYBA, "Nepodařilo se načíst aktuální položku.");
				}
			}

			// jestlize byla smazana polozka nulluju id
			if ((akce != null) && (akce.equalsIgnoreCase("smazat"))) {
				id_long = null;
			}

			Prace aktualniPolozka = null;
			if (id_long != null) {
				try {
					aktualniPolozka = (Prace) hsess.load(Prace.class, id_long);
				} catch (HibernateException e) {
					request.setAttribute(CHYBA, "Nepodařilo se načíst aktuální položku.");
				}
			}
			// neni zadana zadna polozka - vezmu prvni ze seznamu
			else {
				if ((!polozky.isEmpty()) && (!((akce != null) && (akce.equalsIgnoreCase("novy"))))) {
					request.setAttribute("aktualniPolozka", polozky.get(0));
					aktualniPolozka = (Prace) polozky.get(0);
				}
			}
			if (aktualniPolozka != null) {
				PraceForm f = new PraceForm();
				BeanUtils.copyProperties(f, aktualniPolozka);
				f.setId_ukol(aktualniPolozka.getUkol().getId());
				f.setDatum(dateFormat.format(datum));
				request.setAttribute("praceForm", f);
				request.setAttribute("aktualniPolozka", aktualniPolozka);
			}
			tx.commit();
		} catch (HibernateException e) {
			request.setAttribute(CHYBA, "Napodařilo se načíst položky.");
			if (tx != null)
				tx.rollback();
		} catch (Exception e) {
			request.setAttribute(CHYBA, "Napodařilo se načíst položky.");
		} finally {
			hsess.close();
		}

		return mapping.findForward(SUCCESS);
	}

	public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
		throws Exception {

		return mapping.findForward(SUCCESS);
	}

}
