/*
 * server/LineDef.cc:
 *
 * Copyright (C) 2000 John Watson, jwatson@tempusmud.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

#include <iostream>
#include <math.h>

#include "LineDef.h"
#include "SideDef.h"
#include "../util/Persist.h"
#include "Zone.h"
#include "Sector.h"

LineDef::LineDef() {
        modified = false;
        script = 0;
        trigger_flags = 0;
}

void LineDef::load( istream & is, 
                    const class Array<float *> & vs,
                    const class Array<SideDef *> & ss,
                    const class Zone * zone )
{
        unsigned short verts_i[2];
        
        verts_i[0] = Persist::readShort( is );
        verts_i[1] = Persist::readShort( is );
        
        if ( verts_i[0] >= vs.length ||
             verts_i[1] >= vs.length ) {
                cout << " ** Error verts index ( " 
                     << verts_i[0] 
                     << ", " 
                     << verts_i[1] 
                     << " ) on linedef exceeds array length " << vs.length << endl;
                
                verts[0] = verts[1] = 0;
                return;
        }
        
        verts[0] = vs[ verts_i[0] ];
        verts[1] = vs[ verts_i[1] ];

        float dist[2] = {
                verts[1][0] - verts[0][0],
                verts[1][1] - verts[0][1]
        };
                
        length = sqrt( dist[0] * dist[0] + dist[1] * dist[1] );

        //
        // setup the sides pointers
        //
        
        unsigned short sides_i[2];
        
        sides_i[0] = Persist::readShort( is );
        sides_i[1] = Persist::readShort( is );

        if ( sides_i[0] >= ss.length ||
             sides_i[1] >= ss.length ) {
                cout << " ** Error sides index ( " 
                     << sides_i[0] 
                     << ", " 
                     << sides_i[1] 
                     << " ) on linedef exceeds array length " << ss.length << endl;
                
                sides[0] = sides[1] = 0;
                return;
        }
        
        sides[0] = sides[1] = 0;

        if ( sides_i[0] )
                sides[0] = ss[ sides_i[0] ];
        if ( sides_i[1] )
                sides[1] = ss[ sides_i[1] ];

        trigger_flags = Persist::readShort( is );

        short spec_i = Persist::readShort( is );

        if ( spec_i >= 0 )
                script = zone->getScripts()[ spec_i ];
}

void LineDef::writeLine( ostream & os, const class Zone * zone ) const {
        const class Array<float *> & vertexes = zone->getVertexes();
        
        Persist::writeShort( os, vertexes.findElement( verts[0] ) );
        Persist::writeShort( os, vertexes.findElement( verts[1] ) );

        const class Array<class SideDef *> & zone_sides = zone->getSides();

        Persist::writeShort( os, zone_sides.findElement( sides[0] ) );
        if ( sides[1] ) {
                Persist::writeShort( os, zone_sides.findElement( sides[1] ) );
        }
        else {
                Persist::writeShort( os, 0 );
        }

        Persist::writeShort( os, trigger_flags );

        if ( script ) 
                Persist::writeShort( os, zone->getScripts().findElement( script ) );
        else
                Persist::writeShort( os, -1 );
}
