/* WindowSubsystem.java
 * =========================================================================
 * This file is part of the GrInvIn project - http://www.grinvin.org
 * 
 * Copyright (C) 2005-2008 Universiteit Gent
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * A copy of the GNU General Public License can be found in the file
 * LICENSE.txt provided with the source distribution of this program (see
 * the META-INF directory in the source jar). This license can also be
 * found on the GNU website at http://www.gnu.org/licenses/gpl.html.
 * 
 * If you did not receive a copy of the GNU General Public License along
 * with this program, contact the lead developer, or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package org.grinvin.workspace;

import java.awt.Window;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.grinvin.list.WorksheetListModel;
import org.grinvin.io.IOFormatException;
import org.grinvin.io.SectionLoader;
import org.grinvin.io.SectionSaver;
import org.grinvin.io.Subsystem;
import org.grinvin.main.GrinvinWindow;

import org.grinvin.worksheet.WorksheetWindow;
import org.grinvin.workspace.compat.GrinvinWindowWrapper_1_0;
import org.jdom.DataConversionException;
import org.jdom.Element;

/**
 *
 */
public class WindowSubsystem implements Subsystem {
    
    //
    private final Map<String,DefaultWindowWrapper> wrapperMap;
    
    //
    private final WorksheetWindowWrapper wrapper;
    
    //
    private final Map<String, Window> windowMap;
    
    //
    private final GrinvinWindowWrapper grinvinWindowWrapper;
    
    //
    public WindowSubsystem() {
        this.grinvinWindowWrapper = new GrinvinWindowWrapper();

        this.wrapperMap = new LinkedHashMap<String,DefaultWindowWrapper> ();
        wrapperMap.put("EditorWindow",            new EditorWindowWrapper());
        wrapperMap.put("LoggingWindow",           new LoggingWindowWrapper());
        
        this.wrapper = new WorksheetWindowWrapper();
        
        this.windowMap = new HashMap<String, Window>();
    }


    public void init() {
        // initialize standard windows
        for (Map.Entry<String, DefaultWindowWrapper> entry : wrapperMap.entrySet()) {
            Window window = entry.getValue().create();
            windowMap.put(entry.getKey(), window);
            //window.setWindow(entry.getKey(), entry.getValue().create());
        }
        grinvinWindowWrapper.setTempWindowMap(windowMap);
        GrinvinWindow grinvinWindow = grinvinWindowWrapper.create();
        windowMap.put("GrinvinWindow", grinvinWindow);
       
    }

    public void dispose() {
        // dispose of all standard windows
        for (Map.Entry<String, DefaultWindowWrapper> entry : wrapperMap.entrySet()) {
            entry.getValue().dispose(windowMap.get(entry.getKey()));
            //entry.getValue().dispose(window.getWindow(entry.getKey()));
        }
        GrinvinWindow grinvinWindow =(GrinvinWindow)windowMap.get("GrinvinWindow");
        
        //for (WorksheetWindow w: window.getWorksheetListModel().getWorksheetWindowListModel())
        for (WorksheetWindow w: grinvinWindow.getWorksheetListModel().getWorksheetWindowListModel())
            wrapper.dispose(w);
        
        //
        grinvinWindowWrapper.dispose(grinvinWindow);

    }

    public void load(Element root, SectionLoader sloader) throws IOException {
        Element element = root.getChild(getElementName());
        // load standard windows
        for (Map.Entry<String, DefaultWindowWrapper> entry : wrapperMap.entrySet()) {
            Window window = entry.getValue().load(
                    element.getChild(entry.getValue().getElementName()),
                    sloader
                    );
            windowMap.put(entry.getKey(), window);
        }
        
        grinvinWindowWrapper.setTempWindowMap(windowMap);
        GrinvinWindow grinvinWindow = grinvinWindowWrapper.load (element.getChild(grinvinWindowWrapper.getElementName()), sloader);
        windowMap.put("GrinvinWindow", grinvinWindow);
        
        // load graph lists
        String childElementName = wrapper.getElementName();
        WorksheetListModel worksheetListModel = grinvinWindow.getWorksheetListModel();
        for (Object obj : element.getChildren(childElementName))
            worksheetListModel.getWorksheetWindowListModel().add(wrapper.load((Element)obj, sloader));

        try {
            int seqno = element.getAttribute("listSeqNum").getIntValue();
            worksheetListModel.setListSequenceNumber(seqno);
        } catch (DataConversionException ex) {
            throw new IOFormatException("Incorrect integer attribute value", ex);
        }
        
    }
    
    public void load_1_0(Element root, SectionLoader sloader) throws IOException {
        
        GrinvinWindowWrapper_1_0 wrapper = new GrinvinWindowWrapper_1_0(windowMap);
        wrapper.load(root.getChild(wrapper.getElementName()), sloader);

        
    }

    public void save(Element parent, SectionSaver ssaver) throws IOException {
        Element element = new Element(getElementName());
        
        // save standard windows
        for (Map.Entry<String, DefaultWindowWrapper> entry : wrapperMap.entrySet()) {
            entry.getValue().save(windowMap.get(entry.getKey()),
                    element, ssaver );
        }
        
        // save grinvin window
        GrinvinWindow grinvinWindow =(GrinvinWindow)windowMap.get("GrinvinWindow");
        grinvinWindowWrapper.save(grinvinWindow, element, ssaver );
        
        // save graph lists
        element.setAttribute("listSeqNum", Integer.toString(grinvinWindow.getWorksheetListModel().getListSequenceNumber()));
        for (WorksheetWindow w: grinvinWindow.getWorksheetListModel().getWorksheetWindowListModel()) {
            wrapper.save(w, element, ssaver);
        }
        
        parent.addContent(element);
    }

    public String getElementName() {
        return "windowSubsystem";
    }

    public int getMajorVersion() {
        return 1;
    }

    public int getMinorVersion() {
        return 0;
    }

}
