package com.adobe.primetime.reference.manager.test;

import android.util.Log;
import com.adobe.mediacore.*;
import com.adobe.mediacore.EventListener;
import com.adobe.mediacore.timeline.advertising.Ad;
import com.adobe.mediacore.timeline.advertising.AdBreak;
import com.adobe.mediacore.timeline.advertising.AdClick;

import java.util.*;

/**
 * Created by lind on 8/17/15.
 */

public class MediaPlayerEventHandlerUtil {

    private Map<MediaPlayerEventType, List<EventListener>> handlers = new HashMap<MediaPlayerEventType, List<EventListener>>();


    public void addEventListener(EventListener listener)
    {
        MediaPlayerEventType type = getEventType(listener);
        if (type != null)
        {
            if (handlers.containsKey(type))
            {
                handlers.get(type).add(listener);
            }
            else
            {
                List<EventListener> eventHandlers = new ArrayList<EventListener>();
                eventHandlers.add(listener);
                handlers.put(type, eventHandlers);
            }
        }
        else
        {
            throw new UnsupportedOperationException("Type of EventListener added to MockMediaPlayer is not recognized!");
        }
    }

    public void removeEventListener(EventListener listener)
    {
        MediaPlayerEventType type = getEventType(listener);
        if (type != null)
        {
            if (handlers.containsKey(type))
            {
                handlers.get(type).remove(listener);
                if (handlers.get(type).isEmpty())
                {
                    handlers.remove(type);
                }
            }
            else
            {
                throw new IllegalArgumentException("EventListener was not found in list of handlers");
            }
        }
        else
        {
            throw new UnsupportedOperationException("Type of EventListener removed from MockMediaPlayer is not recognized!");
        }

    }

    public void dispatch(MediaPlayerEventType type, Event event) throws ClassCastException, UnsupportedOperationException
    {
        if (!handlers.containsKey(type))
        {
            // do nothing, no handlers for this event
            return;
        }

        List<EventListener> listeners = handlers.get(type);

        for (EventListener l : listeners) {
            switch (type) {
                case kEventStatusChanged:
                    ((StatusChangeEventListener) l).onStatusChanged((MediaPlayerStatusChangeEvent)event);
                    break;
                case kEventSeekPositionAdjusted:
                    ((SeekPositionAdjustedEventListener)l).onPositionAdjusted((SeekEvent)event);
                    break;
                case kEventSeekBegin:
                    ((SeekBeginEventListener)l).onSeekBegin((SeekEvent)event);
                    break;
                case kEventSeekEnd:
                    ((SeekEndEventListener)l).onSeekEnd((SeekEvent)event);
                    break;
                case kEventOperationFailed:

                case kEventLoadInformationAvailable:
                    ((LoadInformationEventListener)l).onLoadInformation((LoadInformationEvent)event);
                    break;
                case kEventSizeAvailable:
                    ((SizeAvailableEventListener)l).onSizeAvailable((SizeAvailableEvent)event);
                    break;
                case kEventRateSelected:
                    ((PlaybackRateSelectedEventListener)l).onRateSelected((PlaybackRateEvent)event);
                    break;
                case kEventRatePlaying:
                    ((PlaybackRatePlayingEventListener)l).onRatePlaying((PlaybackRateEvent)event);
                    break;
                case kEventBufferingBegin:
                    ((BufferingBeginEventListener)l).onBufferingBegin((BufferEvent)event);
                    break;
                case kEventBufferingEnd:
                    ((BufferingEndEventListener)l).onBufferingEnd((BufferEvent)event);
                    break;
                case kEventProfileChanged:
                    ((ProfileChangeEventListener)l).onProfileChanged((ProfileEvent)event);
                    break;
                case kEventAdBreakStarted:
                    ((AdBreakStartedEventListener) l).onAdBreakStarted((AdBreakPlaybackEvent)event);
                    break;
                case kEventAdBreakCompleted:
                    ((AdBreakCompletedEventListener) l).onAdBreakCompleted((AdBreakPlaybackEvent)event);
                    break;
                case kEventAdBreakSkipped:
                    ((AdBreakSkippedEventListener) l).onAdBreakSkipped((AdBreakPlaybackEvent)event);
                    break;
                case kEventAdClicked:
                    ((AdClickedEventListener) l).onAdClicked((AdClickEvent)event);
                    break;
                case kEventAdStarted:
                    ((AdStartedEventListener)l).onAdStarted((AdPlaybackEvent)event);
                    break;
                case kEventAdProgress:
                    ((AdProgressEventListener)l).onAdProgress((AdPlaybackEvent)event);
                    break;
                case kEventAdCompleted:
                    ((AdCompletedEventListener)l).onAdCompleted((AdPlaybackEvent)event);
                    break;
                case kEventTimeChanged:
                    ((TimeChangeEventListener)l).onTimeChanged((TimeChangeEvent)event);
                    break;
                case kEventTimedMetadataAvailable:
                    ((TimedMetadataEventListener)l).onTimedMetadata((TimedMetadataEvent)event);
                    break;
                case kEventDRMMetadataInfoAvailable:
                    ((DRMMetadataInfoEventListener)l).onDRMMetadataInfo((DRMMetadataInfoEvent)event);
                    break;
                case kEventCaptionsUpdated:
                    ((CaptionsUpdatedEventListener)l).onCaptionsUpdated((MediaPlayerItemEvent)event);
                    break;
                case kEventItemCreated:
                    ((ItemCreatedEventListener)l).onItemCreated((MediaPlayerItemEvent)event);
                    break;
                case kEventAudioUpdated:
                    ((AudioUpdatedEventListener)l).onAudioUpdated((MediaPlayerItemEvent)event);
                    break;
                case kEventPlaybackRangeUpdated:
                    ((PlaybackRangeUpdatedEventListener)l).onPlaybackRangeUpdated((MediaPlayerItemEvent)event);
                    break;
                case kEventMainManifestUpdated:
                    ((MainManifestUpdatedEventListener)l).onMainManifestUpdated((MediaPlayerItemEvent)event);
                    break;
                case kEventTimelineUpdated:
                    ((TimelineItemsUpdatedEventListener)l).onItemsUpdated((TimelineEvent)event);
                    break;
                default:
                    throw new UnsupportedOperationException("MediaPlayerEvent type not recognized.");

            }
        }
    }

    private MediaPlayerEventType getEventType(EventListener listener)
    {
        if( listener instanceof StatusChangeEventListener)
            return MediaPlayerEventType.kEventStatusChanged;
        else if( listener instanceof SeekBeginEventListener )
            return MediaPlayerEventType.kEventSeekBegin;
        else if( listener instanceof SeekEndEventListener )
            return MediaPlayerEventType.kEventSeekEnd;
        else if( listener instanceof SeekPositionAdjustedEventListener )
            return MediaPlayerEventType.kEventSeekPositionAdjusted;
        else if( listener instanceof LoadInformationEventListener )
            return MediaPlayerEventType.kEventLoadInformationAvailable;
        else if( listener instanceof SizeAvailableEventListener )
            return MediaPlayerEventType.kEventSizeAvailable;
        else if( listener instanceof PlaybackRateSelectedEventListener )
            return MediaPlayerEventType.kEventRateSelected;
        else if( listener instanceof PlaybackRatePlayingEventListener )
            return MediaPlayerEventType.kEventRatePlaying;
        else if( listener instanceof BufferingBeginEventListener )
            return MediaPlayerEventType.kEventBufferingBegin;
        else if( listener instanceof BufferingEndEventListener )
            return MediaPlayerEventType.kEventBufferingEnd;
        else if( listener instanceof ProfileChangeEventListener )
            return MediaPlayerEventType.kEventProfileChanged;
        else if( listener instanceof AdBreakStartedEventListener )
            return MediaPlayerEventType.kEventAdBreakStarted;
        else if( listener instanceof AdBreakCompletedEventListener )
            return MediaPlayerEventType.kEventAdBreakCompleted;
        else if( listener instanceof AdBreakSkippedEventListener )
            return MediaPlayerEventType.kEventAdBreakSkipped;
        else if( listener instanceof AdStartedEventListener )
            return MediaPlayerEventType.kEventAdStarted;
        else if( listener instanceof AdProgressEventListener )
            return MediaPlayerEventType.kEventAdProgress;
        else if( listener instanceof AdCompletedEventListener )
            return MediaPlayerEventType.kEventAdCompleted;
        else if( listener instanceof AdClickedEventListener )
            return MediaPlayerEventType.kEventAdClicked;
        else if( listener instanceof TimeChangeEventListener )
            return MediaPlayerEventType.kEventTimeChanged;
        else if( listener instanceof TimedMetadataEventListener )
           return MediaPlayerEventType.kEventTimedMetadataAvailable;
        else if( listener instanceof TimelineItemsUpdatedEventListener )
            return MediaPlayerEventType.kEventTimelineUpdated;
        else if( listener instanceof DRMMetadataInfoEventListener )
            return MediaPlayerEventType.kEventDRMMetadataInfoAvailable;
        else if( listener instanceof CaptionsUpdatedEventListener )
            return MediaPlayerEventType.kEventCaptionsUpdated;
        else if( listener instanceof ItemCreatedEventListener )
            return MediaPlayerEventType.kEventItemCreated;
        else if( listener instanceof AudioUpdatedEventListener )
            return MediaPlayerEventType.kEventAudioUpdated;
        else if( listener instanceof PlaybackRangeUpdatedEventListener)
            return MediaPlayerEventType.kEventPlaybackRangeUpdated;
        else if( listener instanceof MainManifestUpdatedEventListener)
            return MediaPlayerEventType.kEventMainManifestUpdated;
        else if( listener instanceof NotificationEventListener)
            return MediaPlayerEventType.kEventOperationFailed;

        return null;
    }

    public enum MediaPlayerEventType {

        kEventStatusChanged,
        kEventSeekPositionAdjusted,
        kEventSeekBegin,
        kEventSeekEnd,
        kEventOperationFailed,
        kEventLoadInformationAvailable,
        kEventSizeAvailable,
        kEventRateSelected,
        kEventRatePlaying,
        kEventBufferingBegin,
        kEventBufferingEnd,
        kEventProfileChanged,
        kEventAdBreakStarted,
        kEventAdBreakCompleted,
        kEventAdBreakSkipped,
        kEventAdClicked,
        kEventAdStarted,
        kEventAdProgress,
        kEventAdCompleted,
        kEventTimeChanged,
        kEventTimedMetadataAvailable,
        kEventDRMMetadataInfoAvailable,
        kEventCaptionsUpdated,
        kEventItemCreated,
        kEventAudioUpdated,
        kEventPlaybackRangeUpdated,
        kEventMainManifestUpdated,
        kEventTimelineUpdated,

    }

}
