Different default status for different activity types?
Not an answer but rather a kind of half temporary workaround, posting in case someone finds it useful, and beacuse you metioned you are familiar with creating an extension/module.

You can use hook_civicrm_buidForm to alter the form status id based on activity type_id/name, this soultion is not user friendly and it won't work from standalone context, ie when using Contacts -> New Activity, but it can do the trick if you can live with that and don't have a ton of Activities Types.

Hope it helps, and let me know if there's anything unclear.

// Implement myextension_civicrm_buildForm 
function myextension_civicrm_buildForm( $formName, &amp;$form ){
    if ( $formName == 'CRM_Activity_Form_Activity' ) {
        // Hook only when adding an Activity and the context is not standalone
        if ( $form-&gt;getAction() == CRM_Core_Action::ADD &amp;&amp; $form-&gt;_context != 'standalone' ) {

            // The array that holds the Status and Activities that should have that status by default
            // and the only bit that you'll have to change/upadte when you add more activities and statuses
            $activities = array( 
                'Completed' =&gt; array( 'Meeting', 'Phone Call' ),
                'No-Show' =&gt; array( 'Custom Activity' ),
                'My Custom Status' =&gt; ( 'Another Custom Activity', 'Yet Another Custom Activity' )
            );

            foreach ($activities as $status =&gt; $activity_types) {
                if ( in_array( $form-&gt;_activityTypeName, $activity_types ) ) {
                    // Get status_id by Label
                    $result = civicrm_api3('OptionValue', 'getsingle', array(
                        'sequential' =&gt; 1,
                        'option_group_id' =&gt; 'activity_status',
                        'label' =&gt; $status,
                    ));
                    // Set the default value in the form
                    $defaults['status_id'] = $result['value'];
                    $form-&gt;setDefaults($defaults);
                }
            }
        }
    } 
}


EDIT
If you want to do the same thing when in standalone context you could add some jQuery/JavaScript to the form, see below updated snippet and JS snippet.

// Implement myextension_civicrm_buildForm 
function myextension_civicrm_buildForm( $formName, &amp;$form ){
    if ( $formName == 'CRM_Activity_Form_Activity' ) {
        // Hook only when adding an Activity and the context is not standalone
        if ( $form-&gt;getAction() == CRM_Core_Action::ADD ) {

            // The array that holds the Status and Activities that should have that status by default
            // and the only bit that you'll have to change/upadte when you add more activities and statuses
            $activities = array( 
                'Completed' =&gt; array( 'Meeting', 'Phone Call' ),
                'No-Show' =&gt; array( 'Custom Activity' ),
                'My Custom Status' =&gt; ( 'Another Custom Activity', 'Yet Another Custom Activity' )
            );

            if( $form-&gt;_context != 'standalone' ){
                foreach ($activities as $status =&gt; $activity_types) {
                    if ( in_array( $form-&gt;_activityTypeName, $activity_types ) ) {
                        // Get status_id by Label
                        $result = civicrm_api3('OptionValue', 'getsingle', array(
                            'sequential' =&gt; 1,
                            'option_group_id' =&gt; 'activity_status',
                            'label' =&gt; $status,
                        ));
                        // Set the default value in the form
                        $defaults['status_id'] = $result['value'];
                        $form-&gt;setDefaults($defaults);
                    }
                }
            } else {
                // Make $activites available in JS
                CRM_Core_Resources::singleton()-&gt;addVars( 'myextension', array( 'defaultedActivites' =&gt; $activities ) );
                // Add JS script
                CRM_Core_Resources::singleton()-&gt;addScriptFile( 'myextension', 'defaultedActivites.js' );
            }
        }
    } 
}

// in your JS script =&gt; defaultedActivites.js
// Same principle as above, there might a better way to do this JS-wise but that should do it
CRM.$(function($) {
    $( '#activity_type_id' ).change( function(){
        var defaultedActivites = CRM.vars.myextension.defaultedActivites; // Store defaultedActivites
        var activity = $( this ).select2( 'data' ); // Get the select2 Activity object, ie Activty type
        $.each( defaultedActivites, function( status, activityTypes ){
            activityTypes.map( function( currentActivity ){
                if( currentActivity == activity.text ){
                    // Get status_id by label
                    CRM.api3( 'OptionValue', 'getsingle', {
                        'sequential': 1,
                        'option_group_id': 'activity_status',
                        'label': status
                    }).done( function( statusId ) {
                        // Set default value
                        $("#status_id").val( statusId.value ).trigger("change");
                    });
                }
            })
        })
    });
});