package com.agna.ferro.core;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

/**
 * base delegate for managing {@link PersistentScreenScope}
 */
public abstract class PSSDelegate {

    private PersistentScreenScope screenScope;
    private HasName screenNameProvider;

    public PSSDelegate(HasName screenNameProvider) {
        this.screenNameProvider = screenNameProvider;
    }

    protected abstract FragmentActivity getParentActivity();

    protected abstract Fragment getParentFragment();

    protected PersistentScreenScope createPersistentScreenScope() {
        return new PersistentScreenScope();
    }

    public PersistentScreenScope getScreenScope() {
        return screenScope;
    }

    public boolean isScreenRecreated() {
        return screenScope.isScreenRecreated();
    }

    public void init() {
        screenScope = PersistentScreenScope.find(getFragmentManager(), screenNameProvider.getName());
        if (screenScope == null) {
            screenScope = createPersistentScreenScope();
            screenScope.attach(getFragmentManager(), screenNameProvider.getName());
        }
        screenScope.setParentActivity(getParentActivity());
        screenScope.setParentPSSFragment(getParentFragment());
    }

    private FragmentManager getFragmentManager() {
        return getParentActivity().getSupportFragmentManager();
    }

    public void onDestroy() {
        if (screenScope != null) {
            screenScope.clearParentActivity();
            screenScope.clearParentPSSFragment();
        }
    }

    public void checkUniqueScreenName() {
        checkUniqueScreenName(getParentActivity());
        for(Fragment fragment : getFragmentManager().getFragments()){
            checkUniqueScreenName(fragment);
        }
    }

    private void checkUniqueScreenName(Object anotherScreen) {
        if (screenNameProvider != anotherScreen) {
            if(HasName.class.isInstance(anotherScreen)){
                String anotherName = ((PSSParentScreen)anotherScreen).getName();
                if(anotherName.equals(screenNameProvider.getName())){
                    throw new IllegalStateException("two screens has same name: "+ anotherScreen
                            + ", " + screenNameProvider);
                }
            }
        }
    }
}

@@ -157,16 +157,41 @@
 Manager;
+%0Aimport android.util.Log;
 %0A%0A/**%0A *
@@ -1691,24 +1691,42 @@
 eenName() %7B%0A
+        try %7B%0A    
         chec
@@ -1773,19 +1773,24 @@
         
+   
+ 
 for
+ 
 (Fragmen
@@ -1838,18 +1838,23 @@
 ments())
+ 
 %7B%0A
+    
         
@@ -1890,16 +1890,209 @@
 gment);%0A
+            %7D%0A        %7D catch (NullPointerException e) %7B%0A            //method HasName#getName() can throw NullPointerException%0A            Log.d(%22PSSDelegate%22, %22checkUniqueScreenName failed%22);%0A
         
@@ -2085,32 +2085,33 @@
 ed%22);%0A        %7D%0A
+%0A
     %7D%0A%0A    priva
@@ -2215,67 +2215,46 @@
 reen
-) %7B%0A            if(HasName.class.isInstance(anotherScreen))
+ && anotherScreen instanceof HasName) 
 %7B%0A  
@@ -2263,20 +2263,16 @@
         
-    
 String a
@@ -2302,16 +2302,17 @@
 tScreen)
+ 
 anotherS
@@ -2341,22 +2341,19 @@
         
-  
-  
 if
+ 
 (another
@@ -2394,16 +2394,17 @@
 Name()))
+ 
 %7B%0A      
@@ -2413,20 +2413,16 @@
         
-  
-  
 throw ne
@@ -2474,16 +2474,17 @@
  name: %22
+ 
 + anothe
@@ -2491,20 +2491,16 @@
 rScreen%0A
-    
         
@@ -2549,26 +2549,8 @@
 r);%0A
-                %7D%0A
     

add safe check unique screen name