# Simple Ren'Py Steam achievement integration.
# (C) 2013-2015 Shiz, badly coded and under no warranty whatsoever.
#
# Grab the Steamworks v1.33a SDK (or whatever the latest version is), extract it, and create the 'game/libs' directory in your Ren'Py game folder.
# Then copy the following files from the SDK:
#   redistributable_bin/steam_api.dll            -> game/libs/steam_api.dll
#   redistributable_bin/osx32/libsteam_api.dylib -> game/libs/libsteam_api.dylib
#   redistributable_bin/linux32/libsteam_api.so  -> game/libs/libsteam_api.so
#   redistributable_bin/linux64/libsteam_api.so  -> game/libs/libsteam_api_64.so
# Then save this file as 'game/steam.py'.
# In your game init code:
#   init python:
#       import steam
#       if steam.loaded:
#           steam.init()
# and when you want to unlock an achievement:
#   $ steam.unlock_achievement('name')
#
import renpy.exports as renpy
import sys
import os.path as path
import ctypes

# Attempt to load the Steam library.
steam = None
wrapper = None
loaded = False

try:
    wrapso = None
    if sys.platform.startswith('win'):
        so = 'steam_api.dll'
    elif sys.platform.startswith('darwin'):
        so = 'libsteam_api.dylib'
        wrapso = 'libsteam_wrapper.dylib'
    elif sys.platform.startswith('linux'):
        if sys.maxsize > 2**32:
            so = 'libsteam_api_64.so'
            wrapso = 'libsteam_wrapper_64.so'
        else:
            so = 'libsteam_api.so'
            wrapso = 'libsteam_wrapper.so'
    else:
        raise EnvironmentError('Unsupported operating system')
    steam = ctypes.CDLL(path.join(renpy.config.gamedir, 'libs', so))
    if wrapso:
        wrapper = ctypes.CDLL(path.join(renpy.config.gamedir, 'libs', wrapso))
except Exception as e:
    if renpy.config.developer:
        raise
    renpy.log('Not loading Steam library: {}'.format(e))
else:
    loaded = True
    # Steam wrappers.
    SteamAPI_Init = steam.SteamAPI_Init
    SteamAPI_Shutdown = steam.SteamAPI_Shutdown
    SteamUserStats = steam.SteamUserStats
    SteamUserStats.restype = ctypes.c_void_p
    if wrapper:
        SteamUserStats_SetAchievement = wrapper.SteamAPIWrapper_SetAchievement
        SteamUserStats_StoreStats = wrapper.SteamAPIWrapper_StoreStats
    else:
        SteamUserStats_SetAchievement = steam.SteamAPI_ISteamUserStats_SetAchievement
        SteamUserStats_StoreStats = steam.SteamAPI_ISteamUserStats_StoreStats

    SteamUserStats_SetAchievement.argtypes = [ ctypes.c_void_p, ctypes.c_char_p ]
    SteamUserStats_StoreStats.argtypes = [ ctypes.c_void_p ]

def init():
    """ Initialize Steam library. May restart program if Steam deems necessary, and loads individual components. """
    # Initialize library.
    try:
        if not SteamAPI_Init():
            raise RuntimeError('Could not initialize Steam library. (SteamAPI_Init() failed)')
    except Exception as e:
        global loaded
        loaded = False
        if renpy.config.developer:
            raise
        renpy.log('Steam initialization failed: {}'.format(e))

def shutdown():
    """ Shut down Steam library. Should be run on exit. """
    # Shut down library.
    global loaded
    if loaded:
        SteamAPI_Shutdown()
        loaded = False

def get_stats():
    """ Get user stats. """
    if loaded:
        return SteamUserStats()

def unlock_achievement(name):
    if loaded:
        stats = get_stats()
        SteamUserStats_SetAchievement(stats, name)
        SteamUserStats_StoreStats(stats)