/***************************************************************************
                          cross.cpp  -  description
                             -------------------
    begin                : Thu Aug 17 2000
    copyright            : (C) 2000 by Waldemar Baraldi
    email                : baraldi@lacasilla.com.ar
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "cross.h"
#include "pointercross.h"

Cross::Cross():Pipe(){
  p=new PointerCross();
  extra_used_input=Void;
  extra_full_level=0;
  ro=Void;
  extra_ro=Void;
}

Cross::~Cross(){
  delete p;
}

bool Cross::hasConnection(CardinalPoint con){
  return (con!=Void);
}

bool Cross::isRemovable(){
  return !((full_level>0) || (extra_full_level>0)) && !fixed;
}

void Cross::restrictAsOutput(CardinalPoint con){
  if (con!=Void)
    if (con==South || con==North)
      ro=con;
    else extra_ro=con;
}

bool Cross::isRestrictedAsOutput(CardinalPoint con){
  return (ro==con || extra_ro==con);
}

CardinalPoint Cross::getOutput(CardinalPoint input){
  if (input==ro || input==extra_ro) return Void;
    switch (input){
      case South: {return North;}
      case North:return South;
      case West: return East;
      case East: return West;
      default:break;
    }
  return Void;
}

void Cross::incFullLevel(CardinalPoint input,unsigned int amount){
  if (!isRestrictedAsOutput(input)){
    if ((input==North) || (input==South))
      if ((used_input==Void) || (used_input==input)){
        full_level+=amount;
        used_input=input;
      }
    if ((input==West) || (input==East))
      if ((extra_used_input==Void) || (extra_used_input==input)){
        extra_full_level+=amount;
        extra_used_input=input;
      }
  }
}

int Cross::getFullLevel(CardinalPoint input){
  if (input==used_input)
    return full_level;
  if (input==extra_used_input)
    return extra_full_level;
  return 0;
}

bool Cross::hasLiquid(){
  return (full_level>0 || extra_full_level>0);
}


Pointer * Cross::getPointer(){
  return p;
}

void Cross::paint(VideoManager * vm){

  Image * ima;
  if (fixed)
    ima=(vm->getImageManager())->getImage(new Str("cross_b.png"));
  else
    ima=(vm->getImageManager())->getImage(new Str("cross.png"));

  vm->blit(ima, x, y);

  if (ro != Void) paintRestriction(vm, ro);
  if (extra_ro != Void) paintRestriction(vm, extra_ro);
  if (full_level>0){
    Image * aux=(vm->getImageManager())->getImage(new Str("flow.png"));
    int xof=x+PipeWidth/2-aux->width()/2;
    int yof=aux->height()/2;
    int total, f;
    vm->setClipping(x, y, PipeWidth, PipeHeight);
    vm->enableClipping(true);
    if (used_input==North){
      total=y-yof;
      f=1;
    }
    else{
      total=PipeHeight+y-yof;
      f=-1;
    }
    for (int i=0; i<full_level+1;i+=Gran)
      vm->blit(aux, xof, (int)(total+f*(float)i/(float)full()*(float)PipeHeight));
    vm->enableClipping(false);
  }
  if (extra_full_level>0){
    Image * aux=(vm->getImageManager())->getImage(new Str("flow.png"));
    int yof=y+(PipeHeight-aux->height())/2;
    int total,f;
    vm->setClipping(x, y, PipeWidth, PipeHeight);
    vm->enableClipping(true);
    if (extra_used_input==West){
      total=x-aux->width()/2;
      f=1;
    }
    else{
      total=x+PipeWidth-aux->width()/2;
      f=-1;
    }
    for (int i=0; i<extra_full_level+1;i+=Gran)
      vm->blit(aux, (int)(total+f*(float)i/(float)full()*(float)PipeWidth), yof);
    vm->enableClipping(false);
  }
  if (bonus!=NormalBonus) paintBonus(vm, bonus);
}
