Index: /trunk/exodus/admin.py
===================================================================
--- /trunk/exodus/admin.py	(revision 6436)
+++ /trunk/exodus/admin.py	(revision 6437)
@@ -2,6 +2,6 @@
 from django.contrib import admin
 from django.contrib import databrowse
-from django import forms
-from exodus.models import *
+from exodus.models import Location, Node, Network, Interface, Antenna, \
+        DnsServer, DhcpStatic        
 from exodus.forms import NodeForm, InterfaceForm
 from exodus.contrib import ReadOnlyAdminFields
@@ -10,25 +10,9 @@
 plain_admin = AdminSite()
 
-#class PublicAPInline(admin.TabularInline):
-#    model = PublicAP
-#    extra = 1
-
-class InterfaceInline(admin.TabularInline):
-    model = Interface
-    form = InterfaceForm
-    extra = 2 
-    fieldsets = (
-        (None, {
-            'classes': ('collapse',),
-            'fields': ('type', 'iface', 'polar', 'antenna', 'link')
-        }),
-    )
-    #inlines = [ PublicAPInline, ] 
-
 class NodeAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
     readonly = ('masterip', )
     form = NodeForm
     list_display = ('name', 'location','network')
-    search_fields = ['name']
+    search_fields = ('name',)
     list_filter = ('network',)
     fieldsets = (
@@ -38,22 +22,19 @@
     )
 
-    inlines = [InterfaceInline, ]
-
-class NodeInline(admin.TabularInline):
-    model = Node
-    form = NodeForm
-    extra = 2 
-    fields = ('name', 'status', 'location', 'network')
-
-class LocationAdmin(admin.ModelAdmin):
-    search_fields = ['description'] 
-    inlines = [ NodeInline, ]
+class InterfaceAdmin(ReadOnlyAdminFields, admin.ModelAdmin):
+    #readonly = ('ip', 'netmask', 'mode', 'ssid', 'shortdesc', 'desc')
+    form = InterfaceForm
+    list_display = ('node', 'iface', 'type', 'ip', 'channel', 'polar', 
+        'shortdesc', 'link')
+    search_fields = ('node__name','iface')
+    list_filter = ('type', 'accesspoint', 'polar', 'node', 'antenna')
+    ordering =('node',)
 
 advanced_admin.register(Antenna)
-advanced_admin.register(Location, LocationAdmin)
+advanced_admin.register(Location)
 advanced_admin.register(DnsServer)
 advanced_admin.register(Network)
 advanced_admin.register(Node, NodeAdmin)
-advanced_admin.register(Interface)
+advanced_admin.register(Interface, InterfaceAdmin)
 #advanced_admin.register(PublicAP)
 advanced_admin.register(DhcpStatic)
Index: /trunk/exodus/forms.py
===================================================================
--- /trunk/exodus/forms.py	(revision 6436)
+++ /trunk/exodus/forms.py	(revision 6437)
@@ -1,9 +1,7 @@
 from django import forms
 from exodus.models import Node, Interface
-from exodus.wllogic import free_master_ip, free_interlink_ip, add_interlink_ip
-from exodus.contrib import ReadOnlyWidget
+from exodus.wllogic import free_master_ip, link_has_compat_type
 
 class NodeForm(forms.ModelForm):
-    #masterip = forms.IPAddressField(widget=forms.HiddenInput)
     class Meta:
        model = Node
@@ -29,2 +27,54 @@
     class Meta:
         model = Interface
+
+    def clean_link(self):
+        import pdb; pdb.set_trace() ;
+        link = self.cleaned_data.get('link')
+    
+        if link:
+            try:
+                # if link is to self we don't need to check anything else
+                if self.instance.pk == link.pk:
+                    return link
+                # Link can't be to same node.
+                if self.instance.node_id == link.node_id:
+                    raise forms.ValidationError(
+                        "A link can't be to another interface on the same node")
+            except Interface.DoesNotExist:
+                pass
+            if self.cleaned_data.get('accesspoint') and \
+                    self.instance.pk != link.pk:
+                raise forms.ValidationError( "A link can't be made to another interface when this interface has an accesspoint.")
+
+            # if link is referenced to itself, link is master and linkable
+            if link.link.pk == link.pk:
+                return link
+
+            # if we get at this elif, it means that link is in managed mode
+            # but masterlink and managed can be switched
+            # And check if that master has only 2, including himself, links
+            # and is not an accesspoint himself.
+            elif len(link.link.interface_set.all()) == 2 and not \
+                    link.link.accesspoint:
+                import pdb; pdb.set_trace() 
+                # convert master to slave
+                #XXX: update mode
+                old_slave = link
+                old_master = old_slave.link
+                old_master.link = old_slave
+                old_slave.link = old_slave
+                old_slave.save()
+                old_master.save()
+                #XXX: do ip address switch stuff
+                return link
+
+            # check if the two links are compatible
+            type = self.cleaned_data.get('type')
+            if not link_has_compat_type(link.type, type):
+                raise forms.ValidationError( 
+                    'Link type %s is not compatible with %s' 
+                    %(link.type, type))
+                
+ 
+        return link
+
Index: /trunk/exodus/models.py
===================================================================
--- /trunk/exodus/models.py	(revision 6436)
+++ /trunk/exodus/models.py	(revision 6437)
@@ -116,6 +116,6 @@
     shortdesc = models.CharField(blank=True, max_length=10)
     desc = models.CharField(blank=True, max_length=100)
+    accesspoint = models.BooleanField()
     link = models.ForeignKey('self', blank=True, null=True)
-    accesspoint = models.BooleanField()
    
     class Meta:
Index: /trunk/exodus/wllogic.py
===================================================================
--- /trunk/exodus/wllogic.py	(revision 6436)
+++ /trunk/exodus/wllogic.py	(revision 6437)
@@ -154,14 +154,11 @@
 		return True
 
-def link_has_compat_type(link1, link2):
-	# if this is a link to self, the link is always valid
-	if link1 == link2:
-		return True
+def link_has_compat_type(type1, type2):
 	# link types must the same
-	if link1.type == link2.type:
+	if type1 == type2:
 		return True
 	# or link types must be compatible
 	compat = ('11b', '11g')
-	if link1.type in compat and link2.type in compat:
+	if type1 in compat and type2 in compat:
 		return True
 
