/***************************************************************************
 * $Id: upnpmanager.cpp,v 1.5 2008/04/14 11:15:53 hoganrobert Exp $
 *   Copyright (C) 2008 by Robert Hogan                                    *
 *   robert@roberthogan.net                                                *
 *                                                                         *
 *   Copyright (C) 2005 by Joris Guisson                                   *
 *   joris.guisson@gmail.com                                               *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/

#include <tdemessagebox.h>
#include "upnpmanager.h"
#include "kdebug.h"

using namespace bt;

UPnPManager* UPnPManager::manager = 0;

    UPnPManager* UPnPManager::Manager () 
    {
      if (manager == 0)
      {  
        manager = new UPnPManager; 
      }
      return manager; 
    }

	UPnPManager::UPnPManager(TQWidget* parent, const char* name)
                 : TQWidget(parent, name)
	{
		sock = new UPnPMCastSocket();
        connect(sock,SIGNAL(discovered( kt::UPnPRouter* )),
                this,SLOT(discovered( kt::UPnPRouter* )));
        discover();
	}
	
	UPnPManager::~UPnPManager()
	{
		delete sock;

	}
	
// 	void UPnPManager::shutdown(bt::WaitJob* job)
// 	{
// 		if (!def_router)
// 			return;
// 		
// 		net::PortList & pl = bt::Globals::instance().getPortList();
// 		if (pl.count() == 0)
// 			return;
// 		
// 		for (net::PortList::iterator i = pl.begin(); i != pl.end();i++)
// 		{
// 			net::Port & p = *i;
// 			if (p.forward)
// 				def_router->undoForward(p,job);
// 		}
// 	}

	void UPnPManager::discover()
	{
        sock->discover();
    }	
	
	void UPnPManager::forward(const net::ForwardPortList &forwardPorts, 
                              bool force, bool silent)
	{
        m_silent = silent;
		TQValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
		while (r != discoveredRouters.end())
		{
            disconnect((*r),SIGNAL(replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )),
                this,SLOT(onReplyError(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )));
            disconnect((*r),SIGNAL(replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )),
                this,SLOT(onReplyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )));

            connect((*r),SIGNAL(replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )),
                    this,SLOT(onReplyError(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )));
            connect((*r),SIGNAL(replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )),
                    this,SLOT(onReplyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const TQString&, bool )));

            for (net::ForwardPortList::ConstIterator i = forwardPorts.begin();
                 i != forwardPorts.end();i++)
            {
                const net::ForwardPort & s = *i;

/*                (*r)->undoForward(net::Port(s.extnumber,s.proto,s.forward),false);*/
                (*r)->forward(net::Port(s.extnumber,s.proto,s.forward),
                              net::Port(s.intnumber,s.proto,s.forward),
                              force);
            }
            r++;
		}

		kdDebug()  << "Done" << endl;
    }

    void UPnPManager::onReplyError(kt::UPnPRouter* router,bt::HTTPRequest* req,const TQString&, bool fwd )
    {

        emit forwardingError(router,req->showPayload(),fwd);
    }

    void UPnPManager::onReplyOK(kt::UPnPRouter* router,bt::HTTPRequest* req,const TQString&, bool fwd )
    {

        kdDebug() << "forwarding OK" << endl;
        emit forwardingOK(router,req->showPayload(),fwd);
    }

	void UPnPManager::undoForward(const net::ForwardPortList &forwardPorts,
                                  bool silent)
	{
        m_silent = silent;
		TQValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
		while (r != discoveredRouters.end())
		{
            for (net::ForwardPortList::ConstIterator i = forwardPorts.begin();i != forwardPorts.end();i++)
            {
                const net::ForwardPort & s = *i;
                (*r)->undoForward(net::Port(s.extnumber,s.proto,s.forward),
                                  net::Port(s.intnumber,s.proto,s.forward), 0);
            }
            r++;
		}

		kdDebug()  << "Done" << endl;
    }

	TQStringList UPnPManager::discoveredRoutersNameList()
	{
        TQStringList routers;
		TQValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
		while (r != discoveredRouters.end())
		{
            routers.append((*r)->getDescription().friendlyName);
            r++;
		}
        return routers;
    }

	void UPnPManager::discovered(UPnPRouter* r)
	{
        discoveredRouters.append(r);
        emit routerDiscovered(r);
    }


	void UPnPManager::unload()
	{
/*		TQString routers_file = TDEGlobal::dirs()->saveLocation("data","tork") + "routers";
		sock->saveRouters(routers_file);*/
		sock->close();
		delete sock;
		sock = 0;
	}
	

#include "upnpmanager.moc"