Index: /trunk/exodus/admin.py
===================================================================
--- /trunk/exodus/admin.py	(revision 6495)
+++ /trunk/exodus/admin.py	(revision 6496)
@@ -32,11 +32,14 @@
     fieldsets = (
         (None, {
-            'fields' : ('node', 'iface', 'type', ('ip', 'netmask'), 'link')}),
+            'fields' : ('node', 'iface', 'type', ('ip', 'netmask'), 'link',
+                        'accesspoint')}),
         ('Wireless', {
             'classes' : ('collapse', ),
-            'fields' : ('ssid', 'channel', 'antenna', 'polar', 'mode')}),
+            'fields' : ('ssid', 'channel', 'antenna', 'polar', 'direction',
+                        'mode')}),
         )
     class Media:
-        js = ("/static/showandhide.js",)
+        js = ("/exodus/media/js/admin/CollapsedFieldsets.js", 
+                "/static/showandhide.js", )        
         
 
Index: /trunk/exodus/forms.py
===================================================================
--- /trunk/exodus/forms.py	(revision 6495)
+++ /trunk/exodus/forms.py	(revision 6496)
@@ -2,5 +2,5 @@
 from exodus.models import Location, Node, Interface
 from exodus.wllogic import free_master_ip, link_has_compat_type, \
-        link_is_wireless, new_ssid
+        link_is_wireless, new_ssid, new_ssid_for_existing_interface
 from exodus.wllogic import MASTER, MANAGED, calc_subnet
 from exodus.settings import AP_NETMASK
@@ -22,6 +22,5 @@
         else:
             # check if network has changed
-            old_network = Node.objects.get(pk=self.instance.pk).network
-            if old_network == self.cleaned_data.get('network'):
+            if self.instance.network == new_network:
                 masterip = self.cleaned_data.get('masterip')
             else:
@@ -29,4 +28,31 @@
                 #XXX: Need to set netmask for interfaces
                 masterip = free_master_ip(new_network) 
+                masterlinks = ( i for i in self.instance.interface_set.all()
+                        if i.id == i.link_id )
+                for i in masterlinks:
+                    all_links = i.interface_set.all()
+                    if i.accesspoint:
+                        netmask = AP_NETMASK
+                    else:
+                        ip_size = len(all_links)
+                        netmask = calc_subnet(ip_size)
+
+                    try:
+                        new_ip = IPCalc(self.instance, netmask, i.id, 
+                                masterip = masterip)
+                    except Exception:
+                        raise forms.ValidationError(
+                            "Not enough free ips for this node.")
+
+                    new_ip.ips.reverse()
+                    i.ip = new_ip.ips.pop()
+                    i.ssid = new_ssid(new_network, self.instance, i.iface, 
+                            i.accesspoint, i.direction)
+                    for j in (j for j in all_links if not j.id == i.pk):
+                        j.ip  = new_ip.ips.pop()
+                        j.netmask = netmask
+                        j.ssid = i.ssid
+                        j.save() 
+                    i.save()
         return masterip        
 
@@ -128,5 +154,5 @@
                     new_slave.type = MANAGED 
                 # update ssids
-                ssid = new_ssid(new_master)
+                ssid = new_ssid_for_existing_interface(new_master)
                 new_master.ssid = ssid
                 new_slave.ssid = ssid
@@ -258,15 +284,73 @@
     def clean_netmask(self):
         """Cleaning happens in clean_ip."""
-        return self.cleaned_data.get('netmask')
+        netmask = self.cleaned_data.get('netmask')
+        link = self.cleaned_data.get('link')
+        edit = bool(self.instance.pk)
+        accesspoint = self.cleaned_data.get('accesspoint')
+
+        if accesspoint:
+            return AP_NETMASK
+
+        if not edit and not link:
+            return 32
+         
+        if not edit and link:
+            return link.netmask
+
+        if self.instance.pk != link.id:
+            return link.netmask
+            
+        if self.instance.pk == link.id:
+            all_links = link.interface_set.all()
+            ip_size = len(all_links)
+            # up ip_size with one if self is not in all_links
+            if not [ x for x in all_links if x.id == self.instance.pk ]:
+                ip_size += 1 
+            return calc_subnet(ip_size)
 
     def clean_ssid(self):
         self.type = self.cleaned_data.get('type')
         edit = bool(self.instance.pk)
+        node = self.cleaned_data.get('node')
+        iface = self.cleaned_data.get('iface')
+        accesspoint = self.cleaned_data.get('accesspoint')
+        direction = self.cleaned_data.get('direction')
+        link = self.cleaned_data.get('link')
+        orig_ssid = self.cleaned_data.get('ssid')
+        
         if not link_is_wireless(self):
             return None
-        if not edit:
-            return new_ssid
-
-        
-
-
+
+        # iface is saved for the first time
+        if not edit and not link: 
+            return new_ssid(node, iface, accesspoint, direction)
+
+        # iface is in managed mode
+        if not edit and link:
+            return link.ssid
+        if self.instance.pk != link.id:
+            return link.ssid
+
+        # iface has become master or
+        # iface changed having accesspoint
+        if self.instance.link_id != link.id or \
+                self.instance.accesspoint != accesspoint:
+            return new_ssid(node, iface, accesspoint, direction)
+        
+        # else, don't change ssid and return original
+        return orig_ssid
+
+    def clean_mode(self):
+        edit = bool(self.instance.pk)
+        link = self.cleaned_data.get('link')
+        
+        if not edit and not link:
+            return MASTER
+
+        if not edit and link:
+            return MANAGED
+
+        if self.instance.pk == link.id:
+            return MASTER
+        
+        return MANAGED
Index: /trunk/exodus/static/showandhide.js
===================================================================
--- /trunk/exodus/static/showandhide.js	(revision 6495)
+++ /trunk/exodus/static/showandhide.js	(revision 6496)
@@ -1,5 +1,9 @@
-var RolandSpecial = {
+var ShowAndHide = {
     init: function() {
-        document.getElementById('id_type').onchange = new Function('RolandSpecial.change(); return false;');
+        document.getElementById('id_type').onchange = new Function('ShowAndHide.change(); return false;');
+        var newValue = document.getElementById('id_type').value;
+        if (newValue != 'eth') {
+            CollapsedFieldsets.show(1);
+        } 
     },
     change: function() {
@@ -13,3 +17,3 @@
 }
 
-addEvent(window, 'load', RolandSpecial.init);
+addEvent(window, 'load', ShowAndHide.init);
Index: /trunk/exodus/wlipcalc.py
===================================================================
--- /trunk/exodus/wlipcalc.py	(revision 6495)
+++ /trunk/exodus/wlipcalc.py	(revision 6496)
@@ -9,10 +9,14 @@
     """
 
-    def __init__(self, node, free_netmask, link_id = None):
+    def __init__(self, node, free_netmask, link_id = None, masterip = None):
         if free_netmask <= MASTERIP_NETMASK or free_netmask > 32:
             raise ValueError, 'Netmask out of bounds.'
 
         self.node = node
-        self.master_ip = node.masterip
+        #XXX: unittest masterip
+        if masterip == None:
+            self.master_ip = node.masterip
+        else:
+            self.master_ip = masterip
         master_netmask = MASTERIP_NETMASK
         self.master_network = wl.get_network(self.master_ip, master_netmask)
@@ -71,5 +75,4 @@
         """Calculate a new network address with a used_list and given netmask.
         """
-        #XXX: network_addr in for loop(generator expression)/list comprehension
         for i in xrange(self.master_ip_size/self.new_ip_size):
             network_addr = wl.parse_addr(self.master_network) + \
Index: /trunk/exodus/wllogic.py
===================================================================
--- /trunk/exodus/wllogic.py	(revision 6495)
+++ /trunk/exodus/wllogic.py	(revision 6496)
@@ -9,8 +9,9 @@
 MANAGED = WIFI_MODE_CHOICES[1][0]
 
-def new_ssid_for_save_iface(nic):
-    return new_ssid(nic.node, nic.iface, nic.accesspoint, nic.direction)
+def new_ssid_for_existing_interface(nic):
+    return new_ssid(nic.network,nic.node, nic.iface, nic.accesspoint, 
+            nic.direction)
 
-def new_ssid(node, iface, accesspoint=False, direction=None):
+def new_ssid(network, node, iface, accesspoint=False, direction=None):
     """Generates a new ssid name for a new wifi NIC.
     
@@ -20,10 +21,10 @@
 
     nodename = node.name 
-    network = node.network.name
+    networkname = network.name
 
     if accesspoint: 
         ssid_list = set([i.ssid for i in \
                 node.interface_set.filter(accesspoint=True)])
-        ssid = "ap%%s.%s.%s" % ( nodename, network) 
+        ssid = "ap%%s.%s.%s" % ( nodename, networkname) 
     
         free_list = set()
@@ -39,5 +40,5 @@
 
     else:
-        ssid = "%%S.%s.%s" % (nodename, network)
+        ssid = "%%s.%s.%s" % (nodename, networkname)
         if direction:
             return ssid % (direction)
