//
//  RBVolumeButtons.m
//  VolumeSnap
//
//  Created by Randall Brown on 11/17/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "LemonVolume.h"
#import <AudioToolbox/AudioToolbox.h>
#import <MediaPlayer/MediaPlayer.h>

@interface LemonVolume()

@property (nonatomic) BOOL isStealingVolumeButtons;
@property (nonatomic) BOOL hadToLowerVolume;
@property (nonatomic) BOOL hadToRaiseVolume;
@property (nonatomic) BOOL suspended;
@property (nonatomic, readwrite) float launchVolume;
@property (nonatomic, retain) UIView *volumeView;

@end

@implementation LemonVolume

static void volumeListenerCallback (
                                    void                      *inClientData,
                                    AudioSessionPropertyID    inID,
                                    UInt32                    inDataSize,
                                    const void                *inData
                                    ){
    const float *volumePointer = inData;
    float volume = *volumePointer;

    if (volume > [(__bridge LemonVolume*)inClientData launchVolume])
    {
        [(LemonVolume*)CFBridgingRelease(inClientData) volumeUp];
    }
    else if (volume < [(__bridge LemonVolume*)inClientData launchVolume])
    {
        [(__bridge LemonVolume*)inClientData volumeDown];
    }
}

- (void)volumeDown
{
    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume, volumeListenerCallback, CFBridgingRetain(self));

    [[MPMusicPlayerController applicationMusicPlayer] setVolume:self.launchVolume];

    [self performSelector:@selector(initializeVolumeButtonStealer) withObject:self afterDelay:0];

    if (self.downBlock)
    {
        self.downBlock();
    }
}

- (void)volumeUp
{
    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume, volumeListenerCallback, CFBridgingRetain(self));

    [[MPMusicPlayerController applicationMusicPlayer] setVolume:self.launchVolume];

    [self performSelector:@selector(initializeVolumeButtonStealer) withObject:self afterDelay:0];

    if (self.upBlock)
    {
        self.upBlock();
    }
}

- (void)startStealingVolumeEvents
{
    NSAssert([[NSThread currentThread] isMainThread], @"This must be called from the main thread");

    if (self.isStealingVolumeButtons)
    {
        return;
    }

    self.isStealingVolumeButtons = YES;

    AudioSessionInitialize(NULL, NULL, NULL, NULL);

    const UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
    
    
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
//    AudioSessionSetActive(YES);

    self.launchVolume = [[MPMusicPlayerController applicationMusicPlayer] volume];
    self.hadToLowerVolume = self.launchVolume == 1.0;
    self.hadToRaiseVolume = self.launchVolume == 0.0;

    // Avoid flashing the volume indicator
    if (self.hadToLowerVolume || self.hadToRaiseVolume)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (self.hadToLowerVolume)
            {
                [[MPMusicPlayerController applicationMusicPlayer] setVolume:0.95];
                self.launchVolume = 0.95;
            }

            if (self.hadToRaiseVolume)
            {
//                [[MPMusicPlayerController applicationMusicPlayer] setValue:0.05 forKey:@"volume"];
                
                [[MPMusicPlayerController applicationMusicPlayer] setVolume:0.05];
                self.launchVolume = 0.05;
            }
        });
    }

    // 避免重复添加MPVolumeView
    for (UIView *subView in [[UIApplication sharedApplication] delegate].window.subviews) {
        if ([subView isKindOfClass:[MPVolumeView class]]) {
            self.volumeView = subView;
            break;
        }
    }
    if (!self.volumeView) {
        self.volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(0, -100, 10, 0)];
        [self.volumeView sizeToFit];
        [[[[UIApplication sharedApplication] delegate] window] addSubview:self.volumeView];
    }

    [self initializeVolumeButtonStealer];

    if (!self.suspended)
    {
        // Observe notifications that trigger suspend
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(suspendStealingVolumeButtonEvents:)
                                                     name:UIApplicationWillResignActiveNotification     // -> Inactive
                                                   object:nil];

        // Observe notifications that trigger resume
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(resumeStealingVolumeButtonEvents:)
                                                     name:UIApplicationDidBecomeActiveNotification      // <- Active
                                                   object:nil];
    }
}

- (void)suspendStealingVolumeButtonEvents:(NSNotification *)notification
{
    if (self.isStealingVolumeButtons)
    {
        self.suspended = YES; // Call first!
        [self stopStealingVolumeEvents];
    }
}

- (void)resumeStealingVolumeButtonEvents:(NSNotification *)notification
{
    if (self.suspended)
    {
        [self startStealingVolumeEvents];
        self.suspended = NO; // Call last!
    }
}

- (void)stopStealingVolumeEvents
{
    NSAssert([[NSThread currentThread] isMainThread], @"This must be called from the main thread");

    if (!self.isStealingVolumeButtons)
    {
        return;
    }

    // Stop observing all notifications
    if (!self.suspended)
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_CurrentHardwareOutputVolume, volumeListenerCallback, CFBridgingRetain(self));

    if (self.hadToLowerVolume)
    {
        [[MPMusicPlayerController applicationMusicPlayer] setVolume:1.0];
    }

    if (self.hadToRaiseVolume)
    {
        [[MPMusicPlayerController applicationMusicPlayer] setVolume:0.0];
    }

    [self.volumeView removeFromSuperview];
    self.volumeView = nil;
    
    [[AVAudioSession sharedInstance] setActive:NO error:nil];
//    AudioSessionSetActive(NO);

    self.isStealingVolumeButtons = NO;
}

- (void)dealloc
{
    self.suspended = NO;
    [self stopStealingVolumeEvents];

    self.upBlock = nil;
    self.downBlock = nil;
}

- (void)initializeVolumeButtonStealer
{
    AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume, volumeListenerCallback, CFBridgingRetain(self));
}

@end
