/***************************** LICENSE START ***********************************

 Copyright 2014 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <algorithm>

#include "FileObject.h"
#include "IconClass.h"
#include "IconFactory.h"
#include "IconInfo.h"
#include "Request.h"
#include "Editor.h"

FileObject::FileObject(Folder* parent, const IconClass& kind,
                       const std::string& name, IconInfo* info) :
    IconObject(parent, kind, name, info)
{
}

void FileObject::doubleClick()
{
    edit();
}

std::set<std::string> FileObject::can()
{
    static std::set<std::string> compressedNames = {"TAR_GZ", "TAR_BZ2", "ZIP", "GZ", "BZ2", "Z"};

    if (className() == "NOTE" || className() == "BINARY") {
        std::set<std::string> s = IconObject::can();
        s.insert("recheck_type");
        return s;
    }
    else if (std::find(compressedNames.begin(), compressedNames.end(), className()) != compressedNames.end()) {
        std::set<std::string> s = IconObject::can();
        s.erase("compress");
        return s;
    }

    return IconObject::can();
}

void FileObject::createFiles()
{
    IconObject::createFiles();
    Path p = path();
    if (!link_ && !p.exists())
        p.touch();
}

Request FileObject::request() const
{
    const char* n = className().c_str();
    Request r(n);
    r("PATH") = path().str().c_str();
    return r;
}

void FileObject::setRequest(const Request& /*r*/)
{
    // IconObject::request(r);
}

// Be extremely careful when calling this function!!
bool FileObject::recheckIconClass()
{
    // Recheck only the NOTE and BINARY icons!!!! The others probably have the correct type!!!
    if (class_->name() == "NOTE" || class_->name() == "BINARY") {
        std::string oriClassName = class_->name();
        const IconClass& actClass = IconClass::guess(path().str());

        // We can only change the iconclass if the new class is still a File or Macro so
        // we can keep the current FileObject (MacroObject is inherited from FileObject!!)
        if (actClass.name() != oriClassName && (actClass.type() == "File" || actClass.type() == "Macro")) {
            class_ = const_cast<IconClass*>(&actClass);

            // TODO: can info be NULL at all?
            if (info_) {
                info_->changeIconClass(class_->name());
            }

            // we need to check everything that depends on the iconclass or
            // stores the current object (and its iconclass!!!)

            // Editable file types:
            //  a) NOTE, MACRO, PYTHON, GEOPOINTS, SQL, KML
            //     can only be edited in a macroEditor - which is a separate process
            //     and we cannot communicate to it (at the moment)
            //  b) SVG
            //     can be edited in inkscape - external editor as well

            if (editor_) {
                editor_->closeIt();
            }

            // there cannot be a queue for a NOTE
            if (queue_) {
            }

            // there cannot be a log for a NOTE
            if (log_) {
            }

            // there cannot be a logwindow for a NOTE
            if (logWindow_) {
            }

            // TODO: check observers
            if (!observers_.empty()) {
            }

            // No dependancy for a file!!!
            // dependancies_

            return true;
        }
    }
    return false;
}

static IconMaker<FileObject> maker1("File");
