/*
 * $Id: EditMessengerAction.java,v 1.22 2008/03/03 15:16:43 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: EditMessengerAction.java,v $
 * Revision 1.22  2008/03/03 15:16:43  korowa
 * bugfixing:Das Feld Subject wird beim Speichern aktualisiert
 *
 * Revision 1.21  2008/02/12 10:38:43  korowa
 * bugfixing: der Betreff wird jetzt kodiert an den DB übergeben
 *
 * Revision 1.20  2008/02/12 09:39:47  korowa
 * + Eine Möglichkeit für den Benutzer hinzugefügt die Emailsart auszuwählen (HTML oder Plaintext)
 * + Betreff für den Messenger der als Emailsubject bei Benachrichtigung übers erscheinen von VKC Dokumenten verschickt wird.
 *
 * Revision 1.19  2004/11/03 13:28:03  marbobo
 * + Einige Funktionen für Gast-Benutzer gesperrt
 *
 * Revision 1.18  2004/10/06 12:33:39  marbobo
 * + Suche nach Globalen Dokument-Attributen korrigiert
 *
 * Revision 1.17  2004/10/05 17:59:51  marbobo
 * + Suche nach Globalen Dokument-Attributen überarbeitet
 *
 * Revision 1.16  2004/09/03 00:42:43  marbobo
 * + Kategorieauswahl über ein Explorer für die Suche eingebaut
 *
 * Revision 1.15  2004/08/26 22:11:27  marbobo
 * + Umgeschrieben wegen Queries
 *
 * Revision 1.14  2004/08/20 15:42:44  jonyp
 * refactoring due to change of VKCSearchQuerySerializer to VKCUserRegSearchQuerySerializer
 *
 * Revision 1.13  2004/08/20 12:46:43  koppy
 * Verwaltung von Quries
 *
 * Revision 1.12  2004/06/27 17:21:29  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.11  2004/03/16 21:14:40  marbobo
 * Überarbeitet
 *
 * Revision 1.10  2004/03/11 20:17:21  bigmac
 * Anpassungen an VKCUserSerializer
 *
 * Revision 1.9  2003/12/24 10:12:06  bigmac
 * Projektweite Import-Optimierung
 *
 * Revision 1.8  2003/12/17 14:44:27  bigmac
 * +Intervallcheck für Schwellwerte eingefügt
 * +Schlüsselwortverarbeitung zeilenbasiert
 *
 * Revision 1.7  2003/10/17 00:53:03  marbobo
 * + Speed-Up beim User-Objekt(reg. Dokumente und Kategorien)
 *
 * Revision 1.6  2003/10/04 16:46:11  marbobo
 * +Dokumentregistrieren
 *
 * Revision 1.5  2003/10/04 02:27:52  marbobo
 * +Kategorienregistrieren mit Unterordnern
 * +kleine Verbesserungen
 *
 * Revision 1.4  2003/09/04 10:12:34  marbobo
 * Code pflege
 *
 * Revision 1.3  2003/08/19 09:21:28  marbobo
 * Bugfix
 *
 * Revision 1.2  2003/08/07 01:57:05  marbobo
 * Bugfix
 *
 * Revision 1.1  2003/08/06 19:40:25  marbobo
 * Initial Version
 *
 */
package vkc.messenger.action;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import vkc.db.entities.VKCKeyword;
import vkc.db.entities.VKCSearchQuery;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCUserSerializer;
import vkc.exception.DBException;
import vkc.messenger.form.EditMessengerForm;
import vkc.misc.VKCLogManager;
import vkc.util.VKCStringUtils;
import vkc.util.sort.KeywordsSortFactory;
import vkc.view.WebShare;
import vkc.view.bean.RegisteredCategory;
import vkc.view.bean.RegisteredDocument;

/**
 * Action-Klasse zum Editieren der Benachrichtigungseinstellungen
 *
 * @author marbobo
 * @version $Revision: 1.22 $
 */
public final class EditMessengerAction extends Action {
	private ActionForward DEFAULT_FORWARD = new ActionForward( "/templates/${template.name}/messenger/editMessenger.jsp" );
	private ActionForward INFO_FORWARD = new ActionForward( "/templates/${template.name}/common/InfoPage.jsp" );
	//~ Methods ----------------------------------------------------------------

	/**
	 * Hier werden die entsprechenden Aktionen eingeleitet 
	 */
	public ActionForward execute( ActionMapping mapping, 
	        					  ActionForm f,
	        					  HttpServletRequest request, 
	        					  HttpServletResponse response )
		throws Exception {
		EditMessengerForm form = (EditMessengerForm)f;

		if ( form.getUser().isGuestUser() ) {
			request.setAttribute( WebShare.INFO_KEY, "vkc.info.access_denied" );
			
			return INFO_FORWARD;
		}

		if ( request.getParameter( "action.save.messenger" ) != null ) {
			return handleSaveMessengerAction( form, request );
		} else if ( request.getParameter( "action.change.category" ) != null ) {
		    return handleChangeCategoryAction( form, request );
		} else if ( request.getParameter( "action.edit.searchquery" ) != null ) {
		    return handleEditSearchQueryAction( form, request );
		} else if ( request.getParameter( "action.create.searchquery" ) != null ) {
		    return handleCreateSearchQueryAction( form, request );
		} else if ( request.getParameter( "action.save.searchquery" ) != null ) {
		    return handleSaveSearchQueryAction( form, request );
		} else if ( request.getParameter( "action.back.searchquery" ) != null ) {
		    form.setEditMode( EditMessengerForm.EDITMODE_MESSENGER );
		    
		    return DEFAULT_FORWARD;
		} 

		return handleInitializeAction( form, request );
	}

	private ActionForward handleChangeCategoryAction( EditMessengerForm form, HttpServletRequest request ) {
		form.getQuery().setSelectedCategoryId( request.getParameter( "selectedCategoryId" ) );
        form.setEditMode( EditMessengerForm.EDITMODE_SEARCHQUERY );

	    return DEFAULT_FORWARD;
	}

    private ActionForward handleCreateSearchQueryAction( EditMessengerForm form, HttpServletRequest request ) {
	    form.getQuery().setQueryId( new Integer( - form.getUniqueId().intValue() ) );
		form.setUniqueId( new Integer( form.getUniqueId().intValue() + 1 ) );
        form.setEditMode( EditMessengerForm.EDITMODE_SEARCHQUERY );

	    return DEFAULT_FORWARD;
    }

    private ActionForward handleEditSearchQueryAction( EditMessengerForm form, HttpServletRequest request ) {
	    form.getQuery().setQuery( (String)form.getDynaValue( "queryId_" + form.getSelectedId() ) );
        form.getQuery().setQueryId( form.getSelectedId() );
	    form.setEditMode( EditMessengerForm.EDITMODE_SEARCHQUERY );

	    return DEFAULT_FORWARD;
    }

    private ActionForward handleSaveSearchQueryAction( EditMessengerForm form, HttpServletRequest request ) {
        if( !form.getQuery().isEmpty() ) {
            if( form.getQuery().getQueryId().intValue() < 1 ) {
                ArrayList queryIds = new ArrayList( Arrays.asList( form.getQueryIds() ) );
                ArrayList selectedQueryIds = new ArrayList( Arrays.asList( form.getSelectedQueryIds() ) );

                if ( !queryIds.contains( form.getQuery().getQueryId() ) ) {
                    queryIds.add( form.getQuery().getQueryId() );
                    selectedQueryIds.add( form.getQuery().getQueryId() );
                    form.setQueryIds( (Integer[])queryIds.toArray( new Integer[ 0 ] ) );
                    form.setSelectedQueryIds( (Integer[])selectedQueryIds.toArray( new Integer[ 0 ] ) );
                }
            }
            
            form.removeDynaValue( "queryId_" + form.getQuery().getQueryId() );
            form.setDynaValue( "queryId_" + form.getQuery().getQueryId(), form.getQuery().getQuery() );
        }
	    
        form.setEditMode( EditMessengerForm.EDITMODE_MESSENGER );
        
        return DEFAULT_FORWARD;
    }

    private ActionForward handleInitializeAction( EditMessengerForm form, HttpServletRequest request ) {
	    form.setEditMode( EditMessengerForm.EDITMODE_MESSENGER );

	    return DEFAULT_FORWARD;
	}
	
	/**
	 * Diese Methode speichert alle Benachrichtigungseinstellungen in die Datenbank
	 * ab
	 */
	private ActionForward handleSaveMessengerAction( EditMessengerForm form, HttpServletRequest request ) throws Exception {
		//Benutzerspezifische Variablen setzen oder initialisieren
		VKCUser user = form.getUser();

		HashMap categories = user.getRegisteredCategories();
		HashMap documents = user.getRegisteredDocuments();
		HashMap userRegisteredCategories = new HashMap();
		HashMap userRegisteredDocuments = new HashMap();
		HashMap userRegisteredQueries = new HashMap();
		Integer[] queryIds = form.getQueryIds();
		Integer[] selectedCategoryIds = form.getSelectedCategoryIds();
		Integer[] selectedSubDirIds = form.getSelectedSubDirIds();
		Integer[] selectedDocumentIds = form.getSelectedDocumentIds();
		Integer[] selectedQueryIds = form.getSelectedQueryIds();

		//zu speichernde Benutzerkategorien bestimmen und im Benutzerform 
		//entsprechend neu setzen
		for ( int i = 0; i < selectedCategoryIds.length; i++ ) {
			RegisteredCategory category = (RegisteredCategory)categories.get( selectedCategoryIds[i] );
			Boolean incSubDirs = Boolean.FALSE;
			
			for ( int j = 0; j < selectedSubDirIds.length; j++ ) {
				if ( category.getCategoryId().intValue() == selectedSubDirIds[j].intValue() ) {
					incSubDirs = Boolean.TRUE;
					break;
				}
			}
            String subject = (String)form.getDynaValue( "categorySubjectId_" + category.getCategoryId().toString() );
			category.setSubjectForNotification(VKCStringUtils.filterUnicodeChars(subject));
            category.setIncludeSubDirs( incSubDirs );
			userRegisteredCategories.put( category.getCategoryId(), category );
		}

		for ( int i = 0; i < selectedDocumentIds.length; i++ ) {
			RegisteredDocument document = (RegisteredDocument)documents.get( selectedDocumentIds[i] );
			String value = (String)form.getDynaValue( "thresholdId_" + document.getDocumentId().toString() );
			String subject = (String)form.getDynaValue( "documentSubjectId_" + document.getDocumentId().toString() );
            Integer threshold = Integer.valueOf( value );
			document.setThreshold( threshold );
            document.setSubjectForNotification(VKCStringUtils.filterUnicodeChars(subject));
			userRegisteredDocuments.put( document.getDocumentId(), document );
		}

		for ( int i = 0; i < selectedQueryIds.length; i++ ) {
			VKCSearchQuery query = new VKCSearchQuery();
			String value = (String)form.getDynaValue( "queryId_" + selectedQueryIds[i] );
            String subject = (String)form.getDynaValue( "querySubjectId_" + selectedQueryIds[i] );
			query.setQuery( value );
            query.setSubjectForNotification(VKCStringUtils.filterUnicodeChars(subject));
			query.setQueryId( selectedQueryIds[i] );

			userRegisteredQueries.put( query.getQueryId(), query );
		}

		Iterator docKeySet = documents.keySet().iterator();
		
		while ( docKeySet.hasNext() ) {
			Integer docId = (Integer)docKeySet.next();
			
			if ( !userRegisteredDocuments.containsKey( docId ) ) {
				form.removeDynaValue( "thresholdId_" + docId.toString() );
			}
		}

		for ( int i = 0; i < queryIds.length; i++ ) {
		    form.removeDynaValue( "queryId_" + queryIds[i] );
		}
		
		user.setRegisteredCategories( userRegisteredCategories );
		user.setRegisteredDocuments( userRegisteredDocuments );
		user.setRegisteredQueries( userRegisteredQueries );
		user.setMessagingEnabled( form.isMessagingEnabled() );
		
		Vector v = VKCStringUtils.stringToVector( form.getKeywordsString(), "\r\n" );
		Set keywordSet = user.getKeywords();
		keywordSet.clear();
		
		for (int i = 0; i < v.size(); i++) {
			String s = vkc.util.StringUtils.normalize( (String)v.elementAt(i) );
			
			if ( s.length() > 0 ) {
				keywordSet.add( new VKCKeyword( s ) );
			}
		}

		// Keywords sortieren für die Ausgabe
		ArrayList keywords = new ArrayList( user.getKeywords() );
		KeywordsSortFactory.sort( keywords, KeywordsSortFactory.SORT_BY_TERM_UP );
		StringBuffer sb = new StringBuffer();
		
		for ( Iterator iter = keywords.iterator(); iter.hasNext() ; ) {
			VKCKeyword keyword = (VKCKeyword)iter.next();
			sb.append( keyword.getTerm() );
			sb.append( '\n' );
		}		
		
		form.setKeywordsString( sb.toString().trim() );

		//Benachrichtigungsintervall des Benutzer entsprechend der Auswahl ändern
		if ( !form.getSelectedMessagingTimePeriod().equals( "" ) ) {
			user.setMessagingTimePeriod( new Integer( form.getSelectedMessagingTimePeriod() ) );
		}

		//Benutzerobjekt in die Datenbank abspeicher
		user.setLastChangerId( user.getUserId() );
		user.setLastChanged( new Timestamp(	System.currentTimeMillis() ) );

		//Speichern des Benutzerobjektes einleiten
		try {
			user.saveRegisteredCategories();
			user.saveRegisteredDocuments();
			user.saveRegisteredQueries();
			
			VKCUserSerializer.saveUser( user );
			
			user.retrieveRegisteredQueries();
			HashMap queries = user.getRegisteredQueries();
			Iterator itQueryKeySet = queries.keySet().iterator();
			ArrayList tmpQueryIds = new ArrayList();

			while ( itQueryKeySet.hasNext() ) {
				Integer queryId = (Integer) itQueryKeySet.next();
				tmpQueryIds.add( queryId );
                form.setDynaValue("querySubjectId_" + queryId, ( (VKCSearchQuery)queries.get( queryId ) ).getSubjectForNotification());
				form.setDynaValue( "queryId_" + queryId.toString(), ( (VKCSearchQuery)queries.get( queryId ) ).getQuery() );
			}
			
			form.setSelectedQueryIds( (Integer[])tmpQueryIds.toArray( new Integer[ 0 ] ) );
			form.setQueryIds( (Integer[])tmpQueryIds.toArray( new Integer[ 0 ] ) );
		    form.setEditMode( EditMessengerForm.EDITMODE_MESSENGER );         

			return DEFAULT_FORWARD;
		} catch ( DBException e ) {
			VKCLogManager.errorLog( this, "1", "Error while saving user profile!", e );
			request.setAttribute( "infokey", "vkc.error.userProfileNotSaved" );

			return INFO_FORWARD;
		}
	}
}