Autofilling fields based on another field
If you want it to happen live, and all fields are on the form already, safest way would be to use hook_form_FORM_ID_alter() to add following to a form:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);


Then in copy_field_value.js create behavior:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);


You can also use hook_form_FORM_ID_alter() to add #ajax parameter to source field, but it would make your form to call a server on each field copy. If you need to actually query database, it is the way to go. It would be pretty broad to describe it anew here. You need to alter $form_state["input"] array to update real values seen by user. Do it in form creation function, wrapping it with isset to avoid notices.

If your form element is $form["something"]["something"]["element"], its value will be in $form_state["input"]["something"]["something"]["element"] - and you can set it in hook_form_alter all right, just remember to take both $form and $form_state by reference.

Note: .on() method was added in jQuery 1.7, so you will need jQuery Update to use this answer directly, or translate my code to use .change() or .blur() method.