package com.atlassian.confluence.extra.workflow;

import com.atlassian.confluence.core.ContentPropertyManager;
import com.atlassian.confluence.event.EventListener;
import com.atlassian.confluence.event.EventManager;
import com.atlassian.confluence.event.events.ConfluenceEvent;
import com.atlassian.confluence.event.events.content.page.PageEvent;
import com.atlassian.confluence.event.events.content.page.PageUpdateEvent;
import com.atlassian.confluence.event.events.content.page.PageViewEvent;
import com.atlassian.confluence.pages.Page;
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: tomd
 * Date: 7/05/2005
 * Time: 21:50:30
 * To change this template use File | Settings | File Templates.
 */
public class PageEditListener implements EventListener
{
    private ContentPropertyManager contentPropertyManager;
    private EventManager eventManager;
    private static Map ignorePages = new HashMap();

    public void handleEvent(ConfluenceEvent event)
    {
        PageEvent pageEvent = (PageEvent) event;
        Page page = (Page)pageEvent.getPage();
        if (isIgnored(page))
        {
            return;
        }
        ignoreEventsForPage(page);
        String eventName;
        if (pageEvent instanceof PageUpdateEvent)
        {
            eventName = PageEditOperation.OPERATION_NAME;
        }
        else
        {
            eventName = PageViewOperation.OPERATION_NAME;
        }

        if (ConfluencePageWorkflowClient.isWorkflowPage(page, contentPropertyManager))
        {
            ConfluencePageWorkflowClient client = new ConfluencePageWorkflowClient(page, contentPropertyManager);
            WorkflowType t = client.getType();
            eventManager.publishEvent(new WorkflowEvent(this,t.getOperationByName(eventName),client,AuthenticatedUserThreadLocal.getUser()));
        }
        acceptEventsForPage(page);
    }

    private boolean isIgnored(Page page)
    {
        return getIgnoreCount(page).intValue() > 0;
    }

    public Class[] getHandledEventClasses()
    {
        return new Class[] {
            PageUpdateEvent.class,
            PageViewEvent.class
        };
    }

    public void setContentPropertyManager(
            ContentPropertyManager contentPropertyManager)
    {
        this.contentPropertyManager = contentPropertyManager;
    }

    private static Integer getIgnoreCount(Page page)
    {
        Integer count = (Integer)ignorePages.get(page.getIdAsString());
        if (count == null)
        {
            count = new Integer(0);
            ignorePages.put(page.getIdAsString(),count);
        }
        return count;
    }

    private static void setIgnoreCount(Page page, int count)
    {
        ignorePages.put(page.getIdAsString(), new Integer(count));
    }

    public static void ignoreEventsForPage(Page page)
    {
        Integer count = getIgnoreCount(page);
        setIgnoreCount(page, count.intValue() + 1);
    }

    public static void acceptEventsForPage(Page page)
    {
        Integer count = getIgnoreCount(page);
        setIgnoreCount(page, count.intValue() - 1);
    }

    public void setEventManager(EventManager eventManager)
    {
        this.eventManager = eventManager;
    }
}
