#include "Finch.h"
#import <AudioToolbox/AudioToolbox.h> 

bool Finch::init()
{
    if (!openAudioSession())
        return false;
    if (!initOpenAL())
        return false;
    return true;
}

Finch::Finch()
{
}

Finch::~Finch()
{
    alcMakeContextCurrent(NULL);
    alcDestroyContext(context);
    alcCloseDevice(device);
    //[super dealloc]; ARC dumb
}

#pragma mark Audio Session

bool Finch::openAudioSession()
{
    OSStatus errcode;
    
    // Initialize the audio session.
    errcode = AudioSessionInitialize(NULL, NULL, NULL, NULL);
    if (errcode) {
        NSLog(@"Error initializing the audio session: %x", errcode);
        return false;
    }

    // Check if some other sound is already playing. I think I, Wade McGillis, wrote this.
    UInt32 userPlayback;
    UInt32 propertySize = sizeof(userPlayback);
    AudioSessionGetProperty(
        kAudioSessionProperty_OtherAudioIsPlaying,
        &propertySize, &userPlayback);
    userMusicPlaying = (userPlayback != 0);

    /*
	 copied from somewhere :/ sorry
	 
    This is a hack. AVAudioPlayer (or maybe somebody lower
    in the audio stack) sometimes refuses to play music, even
    though the OtherAudioIsPlaying property indicates that no
    other music is currently playing. It can be fixed by
    switching to Media Playback session category temporarily.
    */
    if (!userMusicPlaying) {
        sessionCategory = kAudioSessionCategory_AmbientSound;//kAudioSessionCategory_MediaPlayback;
        AudioSessionSetActive(YES);
    }

    setMixWithSystemSound(userMusicPlaying);
        
    errcode = AudioSessionSetActive(YES);
    if (errcode) {
        NSLog(@"Error activating the audio session: %x", errcode);
        return false;
    }
    
    return true;
}

#pragma mark Audio Category

void Finch::setSessionCategory(UInt32 cat)
{
    AudioSessionSetProperty(
        kAudioSessionProperty_AudioCategory,
        sizeof(cat), &cat);
}

UInt32 Finch::getSessionCategory()
{
    UInt32 propertySize = sizeof(UInt32), cat;
    AudioSessionGetProperty(kAudioSessionProperty_AudioCategory,&propertySize, &cat);
    return cat;
}

void Finch::setMixWithSystemSound(bool mix)
{
    sessionCategory = mix ? kAudioSessionCategory_AmbientSound : kAudioSessionCategory_SoloAmbientSound;
}

bool Finch::getMixWithSystemSound()
{
    return (sessionCategory == kAudioSessionCategory_AmbientSound);
}

#pragma mark OpenAL Initialization

bool Finch::initOpenAL()
{
    device = alcOpenDevice(NULL);
    if (!device) {
        NSLog(@"Could not open default OpenAL device.");
        return false;
    }
    
    context = alcCreateContext(device, 0);
    if (!context) {
        NSLog(@"Failed to create OpenAL context for default device.");
        return false;
    }
    
    BOOL success = alcMakeContextCurrent(context);
    if (!success) {
        NSLog(@"Failed to set current OpenAL context.");
        return false;
    }
    
    return true;
}
