Index: E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.module
===================================================================
--- E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.module	(revision 5)
+++ E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.module	(revision 10)
@@ -5,7 +5,7 @@
  * @file
  * Maintains a hierarchy of groups created by the orgainc groups module.
  */
-
+ 
 /**
  * Implementation of hook_perm().
  */
@@ -171,6 +171,7 @@
  */
 function og_subgroups_form_alter(&$form, &$form_state, $form_id) {
   if (isset($form['#node']) && $form_id == $form['#node']->type .'_node_form') {
+    $form['#validate'][] = 'og_subgroups_form_validate';
     $node = $form['#node'];
     if (og_is_group_type($node->type)) {
       // Add the subgroup fields to the node form
@@ -179,14 +180,72 @@
   }
 }
 
+// validate the subgroup value in the node form
+function og_subgroups_form_validate($form, &$form_state) {
+  // Make sure the user is eligible to create a subgroup
+  global $user;
+  $node = node_load($form_state['values']['og_subgroups']['parent']);
+  if(!og_subgroups_is_eligible_to_create_subgroup($node, $user)) {
+    form_set_error('og_subgroups',
+      t('You are not allowed to create a subgroup for %group', array('%group' => $node->title)));
+  }
+}
+
 /**
+ * Implenentation of hook_form_FORM_ID_alter() for node type
+ */
+function og_subgroups_form_node_type_form_alter(&$form, &$form_state) {
+  drupal_add_js(drupal_get_path('module', 'og_subgroups'). '/og_subgroups.js');
+  
+  $og_types = array();
+  $node_types = node_get_types();
+  foreach ($node_types as $type) {
+    if (og_is_group_type($type->type)) {
+      $og_types[] = $type;
+    }
+  }
+
+  $og_types_list = array();
+  foreach ($og_types as $og_type) {
+    $og_types_list[$og_type->type] = $og_type->name;
+  }
+  
+  $form['og']['og_subgroups'] = array(
+    '#prefix' => '<div id="og-group-wrapper">',
+    '#suffix' => '</div>',
+    '#type' => 'fieldset',
+    '#title' => t('Subgroups'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#access' => user_access('administer groups hierarchy'),
+  );
+
+  $form['og']['og_subgroups']['og_subgroups_allowed_subgroup_types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Allowed subgroup types'),
+    '#default_value' => og_subgroups_get_allowed_subgroup_types($form['#node_type']->type),
+    '#options' => $og_types_list,   
+  );
+  $form['og']['og_subgroups']['og_subgroups_privileged_users'] = array(
+    '#type' => 'radios',
+    '#title' => t('Privileged users to create subgroups'),
+    '#default_value' => og_subgroups_get_privileged_users($form['#node_type']->type),
+    '#options' => array(
+      'admins'   => t('Group administrators'),
+      'members'  => t('Group members'),
+      'everyone' => t('Everyone'),   
+    ),
+  );
+}
+
+/**
  * Implementation of hook_form_FORM_ID_alter().
  */
 function og_subgroups_form_node_delete_confirm_alter(&$form, &$form_state) {
   $node = node_load($form['nid']['#value']);
   if (og_is_group_type($node->type)) {
-    $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale');
-    $accessibale = og_subgroups_get_eligable_groups('accessibale');
+    $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale', $node);
+    $accessibale = og_subgroups_get_eligable_groups('accessibale', $node);
     $options = og_subgroups_tree($accessibale, $node->nid, $inaccessibale);
     unset($options[0]);
     $form['target']['#options'] = $options;
@@ -213,8 +272,8 @@
     // Check node is a group type.
     if (og_is_group_type($node->type)) {
       // Get all accessible/ inaccesiable groups for the user.
-      $options = og_subgroups_get_eligable_groups('accessibale');
-      $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale');
+      $options = og_subgroups_get_eligable_groups('accessibale', $node);
+      $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale', $node);
       // Check parent_nid is a valid parent.
       if (array_key_exists($parent_nid, og_subgroups_tree($options, $node, $inaccessibale))) {
         $valid = TRUE;
@@ -282,8 +341,12 @@
     // Only display this block when the user is browsing inside a group:
     $arg = arg(1);
     if ($group_node = og_get_group_context()) {
+      // Get current node
+      $nid = arg(1);
+      $node = node_load($nid);
+      
       $block['subject'] = t('Subgroups');
-      $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale');
+      $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale', $node);
       $block['content'] = og_subgroups_menu_tree($group_node->nid, $group_node->title, $inaccessibale);
     }
 
@@ -400,6 +463,30 @@
 }
 
 /**
+ * Implementation of hook_og_create_links()
+ */
+function og_subgroups_og_create_links($group) {
+  global $user;
+  $subgroup_types = og_subgroups_get_allowed_subgroup_types($group->type);
+  $post_types = og_get_types('group_post');
+  $types = node_get_types();
+  foreach ($subgroup_types as $subgroup_type) {
+    if (og_subgroups_is_eligible_to_create_subgroup($group, $user)) {
+      $type_name = $types[$subgroup_type]->name;
+      $type_url_str = str_replace('_', '-', $subgroup_type);
+      if (module_invoke($types[$subgroup_type]->module, 'access', 'create', $subgroup_type, $user)) {
+        $links["create_$subgroup_type"] = l(t('Create !type', array('!type' => $type_name)), "node/add/$type_url_str", array(
+          'attributes' => array('title' => t('Add a new !type in this group.', array('!type' => $type_name))),
+          'query' => "gids[]=$group->nid",
+          ));
+      }
+    }
+  }
+  return isset($links) ? $links : array();
+}
+
+
+/**
  * Get the parent/ children for a given group node id.
  * 
  * @param $gid
@@ -438,8 +525,18 @@
  * @param $op
  *   The operation
  */
-function og_subgroups_get_eligable_groups($op) {
-  $eligable_groups = og_node_groups_distinguish(og_all_groups_options(), FALSE);
+function og_subgroups_get_eligable_groups($op, $node) {
+  // Get all existing groups
+  $groups = og_all_groups_options();
+  foreach ($groups as $gid => $title) {
+    // Remove groups that their content type 
+    // doesn't allow the current group type as a subgroup
+    $allowed_subgroups = og_subgroups_get_allowed_subgroup_types(node_load($gid)->type);
+    if (!in_array($node->type, $allowed_subgroups)) {
+      unset($groups[$gid]);
+    }
+  }
+  $eligable_groups = og_node_groups_distinguish($groups, FALSE);
   $return = array();
   switch ($op) {
     case 'accessibale':
@@ -463,8 +560,8 @@
  */
 function og_subgroups_form($node) {
   // Get all accessible/ inaccesiable groups for the user.
-  $options = og_subgroups_get_eligable_groups('accessibale');
-  $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale');
+  $options = og_subgroups_get_eligable_groups('accessibale', $node);
+  $inaccessibale = og_subgroups_get_eligable_groups('inaccessibale', $node);
   
   $description = t('The parent group for this group node.');
   if ($inaccessibale) {
@@ -506,11 +603,16 @@
     $form['og_subgroups']['parent'] = array(
       '#type' => 'select',
       '#title' => t('Parent'),
-      '#default_value' => $node->og_subgroups,
+      '#default_value' => $_GET['gids'] ? $_GET['gids'] : $node->og_subgroups,
       '#options' => og_subgroups_tree($options, $node->nid, $inaccessibale),
       '#description' => $description,
     );
   }
+  
+  // Hide subgroup select box if gid is passed in the URL
+  if (!empty($_GET['gids'])) {
+    $form['og_subgroups']['#collapsed'] = TRUE;
+  }
 
   return $form;
 }
@@ -548,7 +650,7 @@
     // Set the top level group. Make sure the gid is part of the accessible groups.
     if (empty($tree[$gid]) && $gid != $exclude) {
       !in_array($gid, $inaccessibale) ? $tree[$gid] = $title : $tree[$gid] = t('<private group>');
-      $tree = og_subgroups_tree_recurse($gid, $exclude, $inaccessibale, $tree, $indent .'--');
+      $tree = og_subgroups_tree_recurse($gid, $groups, $exclude, $inaccessibale, $tree, $indent .'--');
     }
 
   }
@@ -558,13 +660,13 @@
 /**
  * Helper function for og_subgroups_tree().
  */
-function og_subgroups_tree_recurse($gid, $exclude, $inaccessibale, $tree, $indent) {
+function og_subgroups_tree_recurse($gid, $groups, $exclude, $inaccessibale, $tree, $indent) {
   $children = og_subgroups_get_family($gid, 'down'); 
   foreach ($children as $node) {
-    if ($node->gid != $exclude) {
+    if ($node->gid != $exclude && in_array($gid, $groups)) {
       !in_array($node->gid, $inaccessibale) ? $title = $node->title : $title = ('<private group>');
       $tree[$node->gid] = $indent .' '. $title;
-      $tree = og_subgroups_tree_recurse($node->gid, $exclude, $inaccessibale, $tree, $indent .'--');
+      $tree = og_subgroups_tree_recurse($node->gid, $groups, $exclude, $inaccessibale, $tree, $indent .'--');
     }
   }
   return $tree;
@@ -945,3 +1047,46 @@
     return $tokens;
   }
 }
+
+function og_subgroups_get_allowed_subgroup_types($group_type) {
+  return variable_get('og_subgroups_allowed_subgroup_types_' . $group_type, array());
+}
+
+function og_subgroups_get_privileged_users($group_type) {
+  return variable_get('og_subgroups_privileged_users_' . $group_type, 'everyone');
+}
+
+/*
+ * Helper function to check if a user is eligible to create
+ * a subgroup for a group node
+ * 
+ * @param $node
+ *    The group node
+ *
+ * @param $user
+ *    The user
+ *
+ * @return
+ *    TRUE if user can create a subgroup. Otherwise, FALSE
+ */
+function og_subgroups_is_eligible_to_create_subgroup($node, $user) {
+  $eligible_users = og_subgroups_get_privileged_users($node->type);
+  switch ($eligible_users) {
+  case 'admins':
+    if (og_is_group_admin($node, $user)) {
+      return TRUE;
+    }
+    return FALSE;
+    break;
+  case 'members':
+    if (og_is_group_member($node, $user)) {
+      return TRUE;
+    }
+    return FALSE;
+    break;
+  case 'everyone':
+  default:
+    return TRUE;
+    break;
+  }
+}
Index: E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.install
===================================================================
--- E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.install	(revision 5)
+++ E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.install	(revision 10)
@@ -40,6 +40,13 @@
     'og_subgroups_propagate_members',
     'og_subgroups_propagate_demote',
   );
+  $node_types = node_get_types();
+  foreach ($node_types as $node_type) {
+    if (og_is_group_type($node_type->type)) {
+      $variables[] = 'og_subgroups_allowed_subgroup_types_' . $node_type->type;
+      $variables[] = 'og_subgroups_privileged_users_' . $node_type->type;
+    }
+  }
   foreach ($variables as $variable) {
     variable_del($variable);
   }
Index: E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.js
===================================================================
--- E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.js	(revision 0)
+++ E:/xampp/htdocs/itsite/sites/all/modules/og_subgroups/og_subgroups.js	(revision 10)
@@ -0,0 +1,16 @@
+// Content type form
+Drupal.behaviors.og_subgroups_content_type = function() {
+  // Disable the subgroup types selection if the content type usage is not group_node
+  $('input[name="og_content_type_usage"]').click(function(){
+    if (!$('#edit-og-content-type-usage-group').attr('checked')) {
+      $('#og-group-wrapper :input').attr('disabled','disabled');
+    } else {
+      $('#og-group-wrapper :input').removeAttr('disabled');
+    }
+  });
+  
+  // Initial check to see if content type is group node
+  if (!$('#edit-og-content-type-usage-group').attr('checked')) {
+    $('#og-group-wrapper :input').attr('disabled','disabled');
+  }
+}
